1. 程式人生 > >2018-2019賽季多校聯合新生訓練賽第七場(2018/12/16)補題題解

2018-2019賽季多校聯合新生訓練賽第七場(2018/12/16)補題題解

感慨

這次還是有不少題挺靠思維的

A 面積(語法基礎)

這個公式都記得啊應該就是S=(上底+下底)*高/2

程式碼

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int a,b,c;
    cin>>a>>b>>c;
    int ans=(a+a+2*c)*b/2;
    cout<<ans;
}

B 網路訊號(語法基礎)

都是在一條直徑上走,那不就是一個數軸上走閉區間麼?

程式碼

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int r,n,ans=0,re=0;
    cin>>r>>n;
    for(int i=0;i<n;i++)
    {
        int t;
        cin>>t;
        re+=t;
        if(re>=-r&&re<=r)
        ans++;
    }
    cout<<ans;
}

C 排隊I(思維)

這個資料到了1e5,樸素的O(N*N)的演算法絕對是要超時的,那麼應該怎麼辦呢?

實際上就一句話,掃一遍,把之前出現的陣列放到bk數組裡面,然後遍歷當前數比這個數大的bk陣列的數值,加起來。

加起來的意思就是之前已經記錄了多少個比他大的數,這樣就是線性的時間了

程式碼

#include <bits/stdc++.h>
using namespace std;
int bk[1200];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin>>n;
  for(int i=0;i<n;i++)
  {
    int t,sum=0;
    cin>>t;
    bk[t]++;
    for(int j=t+1;j<=120;j++)
    sum+=bk[j];
    cout<<sum<<" ";
  }
}

D 覆蓋(模擬)

這個題有不少細節我就說一下我的思路,具體細節還是自己研究研究就行

①先算男生拖的地,這個時候女生還沒有拖地,所以直接算一行的

②然後再算女生拖的,女生拖的地是男生沒有脫的行數*女生覆蓋的列數

③如果男生不拖,是0,那麼就直接算女生的

④具體的標記可以在每行每列給出

程式碼

#include <bits/stdc++.h>
using namespace std;
int bk[5005][5005];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,m,b,g,sum=0,ans1=0;
  cin>>n>>m>>b>>g;
  for(int i=0;i<b;i++)
  {
    int x,y;
    cin>>x>>y;
    for(int j=x;j<=y;j++)
    bk[j][0]++;
  }
  for(int i=0;i<g;i++)
  {
    int x,y;
    cin>>x>>y;
    for(int j=x;j<=y;j++)
    bk[1][j]++;
  }
  if(b>0)
  {
  for(int i=1;i<=n;i++)
  if(bk[i][0]==0)
  ans1++;
  sum+=m*(n-ans1);
  for(int i=1;i<=m;i++)
  if(bk[1][i])
  sum+=ans1;
  cout<<sum;
}
else
{
  for(int i=1;i<=m;i++)
  if(bk[1][i])
  sum+=n;
  cout<<sum;
}
}

E 遊戲(模擬)

先算出最小公倍數,作為最小週期數,然後算出最小週期內贏的次數,再把餘下的加上就行了

程式碼

#include <bits/stdc++.h>
using namespace std;
int num1[1000];
int num2[1000];
int gcd(int a,int b)
{
  return b==0?a:gcd(b,a%b);
}
int check(int a,int b)
{
  if(a==1)
  {
    if(b==2)
    return 1;
    else return 0;
  }
  if(a==2)
  {
    if(b==3)
    return 1;
    else return 0;
  }
  if(a==3)
  {
    if(b==1)
    return 1;
    else return 0;
  }
}
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,m,k,sum=0,ans=1;
  cin>>n>>m>>k;
  int t=n*m/gcd(n,m);
  for(int i=1;i<=n;i++)
  cin>>num1[i];
  for(int i=1;i<=m;i++)
  cin>>num2[i];
  for(int i=1;i<=t;i++)
  {
    if(check(num1[(i-1)%n+1],num2[(i-1)%m+1]))
    sum++;
  }
  if(k<=t)
  {
    for(int i=1;i<=k;i++)
    {
      if(check(num1[(i-1)%n+1],num2[(i-1)%m+1]))
      ans++;
    }
    cout<<ans;
  }
  else
  {
    ans*=(k/t)*sum;
    k%=t;
    for(int i=1;i<=k;i++)
    {
      if(check(num1[(i-1)%n+1],num2[(i-1)%m+1]))
      ans++;
    }
    cout<<ans;
  }
}

F 差(思維)

又是一個樸素O(N*N)超時的題,還得尋找別的方法

實際上這裡去記錄每個差值的數,然後加上這個差值所包含的數,因為資料給出就是升序的,所以不用排序,然後把每次數的數量記錄一下

注意如果差值是一個負數那麼可以不用記錄,因為那樣沒有什麼意義

例如樣例

4 1
1 1 2 2
1-1=0
sum+=bk[0]=0
bk[1]=1
表明1已經出現了1次了
1-1=0
sum+=bk[0]=0
bk[1]-2
表明1已經出現了2次了
2-1=1
sum+=bk[1]=2
bk[2]=1
2-1=1
sum+=bk[1]=4
bk[2]=2
所以答案是4

程式碼

#include <bits/stdc++.h>
using namespace std;
map<long long,long long> bk;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long n,c,sum=0;
  cin>>n>>c;
  for(int i=0;i<n;i++)
  {
    int t;
    cin>>t;
    if(t-c>=0)
    sum+=bk[t-c];
    bk[t]++;
  }
  cout<<sum;
}

G 成績統計(語法基礎)

程式碼

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,you=0,liang=0,zhong=0,cha=0;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        int t;
        cin>>t;
        if(t>=90&&t<=100)
        you++;
        else if(t>=80&&t<=89)
        liang++;
        else if(t>=60&&t<=79)
        zhong++;
        else if(t<60)
        cha++;
    }
    cout<<"You "<<you<<"\n";
    cout<<"Liang "<<liang<<"\n";
    cout<<"Zhong "<<zhong<<"\n";
    cout<<"Cha "<<cha<<"\n";
}

H 列印圖形II(語法基礎)

程式碼

#include <bits/stdc++.h>
using namespace std;
string st[12321];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,you=0,liang=0,zhong=0,cha=0;
    cin>>n;
    for(int i=n;i;i--)
    {
        string t="",tt="",ttt="";
        for(int j=i;j;j--)
        t+=char('A'+n-j);
        for(int j=0;j<t.size()-1;j++)
        tt+=t[j];
        reverse(tt.begin(),tt.end());
        for(int j=0;j<n-i;j++)
        ttt+=' ';
        st[i]=ttt+t+tt;
    }
    for(int i=n;i;i--)
    cout<<st[i]<<"\n";
    for(int i=2;i<=n;i++)
    cout<<st[i]<<"\n";
}

I 數值計算(基礎程式設計)

直接暴力啊,這個題資料這麼小

程式碼

#include <bits/stdc++.h>
using namespace std;
string st[12321];
int isp(int n)
{
    for(int i=2;i*i<=n;i++)
    if(n%i==0)
    return 0;
    return 1;
}
int check(int n)
{
    double a=sqrt(n);
    int b=sqrt(n);
    if(a==b)
    return 1;
    else
    return 0;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int l,r,sum=0;
    cin>>l>>r;
    for(int i=l;i<=r;i++)
    {
        if(!isp(i))
        continue;
        stringstream s;
        s<<i;
        string te,t1="",t2="";
        s>>te;
        t1+=te[0];t1+=te[1];
        t2+=te[2];t2+=te[3];
        stringstream ss,sss;
        ss<<t1;sss<<t2;
        int n1,n2;
        ss>>n1;sss>>n2;
        if(check(n1)&&check(n2))
        cout<<i<<"\n",sum++;
    }
    cout<<sum;
}

J 字串VII(字串基礎)

這題還因為沒有看清楚插入的位置錯了兩次

程式碼

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    string a;
    cin>>a;
    int t;
    cin>>t;
    string b;
    cin>>b;
    cout<<a.size()<<"\n"<<a.find("a")+1<<"\n";
    a.insert(t-1,b);
    cout<<a;
}

K 身高排隊(排序)

注意這裡有個四捨五入,別的應該沒啥特別的了

程式碼

#include <bits/stdc++.h>
using namespace std;
int num[2333][2333],st[23333333];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,m,p=0,ans=0;
    double sum=0;
    cin>>n>>m;
    for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
    cin>>num[i][j],st[p++]=num[i][j],sum+=num[i][j];
    for(int i=0;i<m;i++)
    {
        int maxn=-1;
        for(int j=0;j<n;j++)
        {
            if(num[j][i]>maxn)
            maxn=num[j][i];
        }
        cout<<maxn<<"\n";
    }
    double avg=sum/(n*m);
    avg+=0.5;
    int ag=int(avg);
    sort(st,st+p,cmp);
    for(int i=0;i<p;i++)
    {
        if(st[i]>=ag)
        ans++;
        cout<<st[i]<<" ";
    }
    cout<<"\n"<<ag<<"\n"<<ans;
}

L 階乘後K位(數學)

這個題,我在比賽的時候差點做出來了,因為一個細節沒有注意

我直接乘冪然後餘的100億發現這樣也不對,然後把最後的10位拿掉也不對,實際上階乘最後會出現一堆0,而題目又要去掉最終答案的0.

因為0對於乘數來說沒有任何貢獻,所以我們應該先把0去掉然後再進行餘10億,最後注意一下高位補0,其他的就沒啥了

程式碼

#include <bits/stdc++.h>
using namespace std;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,k;
  cin>>n>>k;
  long long ans=1;
  for(int i=1;i<=n;i++)
  {
    ans*=i;
    while(ans%10==0)
    ans/=10;
    ans%=10000000000;
  }
  stringstream s;
  s<<ans;
  string ss;
  s>>ss;
  for(int i=ss.size();i<k;i++)
  ss='0'+ss;
  for(int i=ss.size()-k;i<ss.size();i++)
  cout<<ss[i];
}

M 尋找指定的特殊素數(數學)

超級大水題,根本到不了100就要error,這次還因為題目裡的歎號是中文的標點,而上傳的歎號是英文的,這個弄的我這個題一血沒了,過了一個小時才猜出來這裡可能有錯,期間還交了1 2次,加了幾次罰時

具體我是打表做的,至於怎麼打表,直接暴力就可以了。篩出來素數然後一點一點的暴力,打表很快的

打表的程式碼

#include <bits/stdc++.h>
using namespace std;
int bk[100000005];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    for(int i=2;i*i<=100000000;i++)
    if(!bk[i])
    for(int j=i*i;j<=100000000;j+=i)
    bk[j]=1;
    bk[1]=1;
    for(int k=1;k<=8;k++)
    {
        int n,m,l=1,ff=0,sum=0;
        for(int i=0;i<k-1;i++)
        l*=10;
        for(int i=l;i<=l*10;i++)
        {
            if(bk[i])
            continue;
            int k=i,f=0;
            k/=10;
            while(k)
        {
            if(bk[k])
            {
                f=1;
                break;
            }
            k/=10;
        }
        if(!f)
        sum++,cout<<i<<",";
        /*if(sum==m)
        {
            cout<<i;
            ff=1;
            break;
        }*/
    }
    cout<<"\n"<<sum<<"\n";
}
}

提交的程式碼

#include <bits/stdc++.h>
using namespace std;
int db1[]={2,3,5,7};
int db2[]={23,29,31,37,53,59,71,73,79};
int db3[]={233,239,293,311,313,317,373,379,593,599,719,733,739,797};
int db4[]={2333,2339,2393,2399,2939,3119,3137,3733,3739,3793,3797,5939,7193,7331,7333,7393};
int db5[]={23333,23339,23399,23993,29399,31193,31379,37337,37339,37397,59393,59399,71933,73331,73939};
int db6[]={233993,239933,293999,373379,373393,593933,593993,719333,739391,739393,739397,739399};
int db7[]={2339933,2399333,2939999,3733799,5939333,7393913,7393931,7393933};
int db8[]={23399339,29399999,37337999,59393339,73939133};
int c[100];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,m;
  cin>>n>>m;
  c[1]=4,c[2]=9,c[3]=14,c[4]=16,c[5]=15,c[6]=12,c[7]=8,c[8]=5;
  if(m>c[n])
  cout<<"Error!";
  else
  {
    if(n==1)
    cout<<db1[m-1];
    if(n==2)
    cout<<db2[m-1];
    if(n==3)
    cout<<db3[m-1];
    if(n==4)
    cout<<db4[m-1];
    if(n==5)
    cout<<db5[m-1];
    if(n==6)
    cout<<db6[m-1];
    if(n==7)
    cout<<db7[m-1];
    if(n==8)
    cout<<db8[m-1];
  }
}