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)超时的题,还得寻找别的方法

实际上这里去记录每个差值的数,然后加上这个差值所包含的数,因为数据给出就是升序的,所以不用排序,然后把每次数的数量记录一下

注意如果差值是一个负数那么可以不用记录,因为那样没有什么意义

实际上这个东西就是把A-B=C移项变成了A-C=B然后记录B有多少

例如样例

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];
  }
}
posted @ 2018-12-17 00:34  baccano!  阅读(456)  评论(0编辑  收藏  举报