2019寒假集训第五场(新生场)(补题题解)

这次比赛有事么的参加,托人交了几个题。。。

A: 水题大战(语法基础)

原题cf 512div2 A In Search of an Easy Problem

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin>>n;
  while(n--)
  {
    int t,f=0;
    cin>>t;
    while(t--)
    {
      int m;
      cin>>m;
      if(m==1)
      f=1;
    }
    if(f)
    cout<<"HARD\n";
    else
    cout<<"EASY\n";
  }
}

B 学生分组(语法基础)

排序一次每两个取差值即可

代码

#include <bits/stdc++.h>
using namespace std;
int num[666666];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,ans=0;
  cin>>n;
  for(int i=0;i<n;i++)
  cin>>num[i];
  sort(num,num+n);
  for(int i=0;i<n;i+=2)
  ans+=abs(num[i]-num[i+1]);
  cout<<ans<<"\n";
}

C 变换高度(贪心)

首先这个题要先贪心的想一下什么情况下会友好的最少

那么应该把移动的砖块尽可能的往k上去靠

所以我就猜的要从高度高的到低的去枚举

因为这样能够最大化的去利用每一层的砖块让他去到达k

一层一层的枚举如果砖块加吧起来总共大于k了,那么ans++,原先的sum归零

如果所有的砖块都一样高了,那么就可以断定已经满足了要求

具体看代码

#include <bits/stdc++.h>
using namespace std;
int bk[666666];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,k,maxn=-1,minn=999999999,ans=0,sum=0;
  cin>>n>>k;
  for(int i=0;i<n;i++)
  {
    int t;
    cin>>t;
    maxn=max(maxn,t);
    minn=min(minn,t);
    bk[t]++;
  }
  for(int i=maxn;i>=minn;i--)
  {
    if(bk[i]==n)
    {
      if(sum)
      ans++;
      break;
    }
    if(sum+bk[i]<=k)
    sum+=bk[i];
    else
    {
      ans++;
      sum=0;
      if(sum+bk[i]<=k)
      sum+=bk[i];
    }
    bk[i-1]+=bk[i];
    bk[i]=0;
    //cout<<sum<<"\n";
  }
  cout<<ans;
}

D 统计序列(数学)

待填坑

E 统计字数(语法基础)

代码

#include <bits/stdc++.h>
using namespace std;
int num[666666];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int sum1=0,sum2=0;
  string a;
  getline(cin,a);
  for(int i=0;i<a.size();i++)
  if(isalpha(a[i]))
  sum1++;
  else if(isdigit(a[i]))
  sum2++;
  cout<<sum1<<" "<<sum2;
}

F 整数拆分(字符串基础)

字串那就是连续的如果是子序列的话。。。

直接枚举即可

代码

#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 b,sum=0;
  cin>>b;
  for(int i=0;i<a.size();i++)
  {
    string t="";
    if(a[i]=='0')
    continue;
    for(int j=i;j<a.size();j++)
    {
      t+=a[j];
      stringstream s;
      s<<t;
      int c;
      s>>c;
      if(c>b)
      sum++;
    }
  }
  cout<<sum;
}

G 真假鉴定(思维)

实际上如果都是真的或者都是假的话一下子就能验证出来

而存在多样性的只有子序列中包含真的且包含假的情况下才有可能发生

多样性怎么才一定发生呢

实际上可以进行一波猜测

如果都拿出相同的硬币,那么多样性是一定存在的。因为不知道到底哪一些是真的哪一些是假的

所以要保证拿出的各个硬币都得不一样

这里还有一个问题

怎么去拿?

实际上只要保证硬币从1开始单增的拿就能保证多样性发生的概率最小,因为这样就保证的每个数能够分成去的硬币的可能变大

那么如果拿不出这些硬币那就肯定存在了多样性,所以

根据输入的前缀的形式,以后所有的输出都得预先+1

具体看代码

代码

#include <bits/stdc++.h>
using namespace std;
int num[666666];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,sum=1,ans=1;
  cin>>n;
  for(int i=0;i<n;i++)
  cin>>num[i];
  for(int i=0;i<n;i++)
  {
    if(num[i]>=sum)
    cout<<ans<<"\n",sum++;
    else
    {
      ans++;
      cout<<ans<<"\n";
    }
  }
}

H 最大公约数(数论)

原题是cf 511div2 C Enlarge GCD

这里我也没有搞懂具体怎么实现的好所以我先贴一下cf福建高中生出题人团队题解吧

解法

First we divide all numbers by GCD of them. Then we should find a subset with maximum number of integers GCD of which is bigger than 1.

We can enumerate a prime p that GCD of the remaining integers can be divided by. And the number of integers can be divided by p is the maximum size of the subset.

We can use Sieve of Euler to factor all integers in time. Then we find the prime that can divide most integers. The answer is n minus the number of integers can be divided by this prime. If all integers are 1 (after dividing their GCD), there is no solution.

代码

#include<bits/stdc++.h>
using namespace std;
#define MN 300000
#define MX 15000000
int a[MN+5],u[MX+5],p[MX+5],pn,s[MX+5];
int gcd(int x,int y){return y?gcd(y,x%y):x;}
int main()
{
    int n,i,j,g,x,ans=0;
    for(i=2;i<=MX;++i)
    {
        if(!u[i])u[i]=p[++pn]=i;
        for(j=1;i*p[j]<=MX;++j){u[i*p[j]]=p[j];if(i%p[j]==0)break;}
    }
    scanf("%d",&n);
    for(g=0,i=1;i<=n;++i)scanf("%d",&a[i]),g=gcd(g,a[i]);
    for(i=1;i<=n;++i)for(j=a[i]/g;j>1;)for(++s[x=u[j]];u[j]==x;)j/=u[j];
    for(i=1;i<=MX;++i)ans=max(ans,s[i]);
    printf("%d",ans?n-ans:-1);
}

猜你喜欢

转载自www.cnblogs.com/baccano-acmer/p/10317378.html