Codeforces Round #499 (Div. 2)ABCDE比赛总结

只做了三道题,rank1100+,居然上了1分。。。分数太低了。。。

A:给你n个字母,挑m个不连续、不相同的字母,看能不能挑出来a——z权值为1——26,能挑出来就输出挑出来的总权值。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=200010;
int n,m,k;
int a[maxn],sum[maxn];
int c[maxn];
int ans,ct,cnt,tmp,flag;
char s[maxn];
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        scanf("%s",s);
        ans=0;   flag=1;
        memset(c,0,sizeof(c));
        int l=strlen(s);
        for(int i=0;i<l;i++){
            a[i]=s[i]-'a'+1;
        }
        sort(a,a+n);
        int ans=a[0];
        flag=a[0];
        int k=1;
        if(m==k){printf("%d\n",ans);continue;}
        for(int i=1;i<l;i++)
        if(a[i]-flag>1){
            ans+=a[i];
            k++;
            if(m==k) break;
            flag=a[i];
        }
        if(k<m) puts("-1");
        else printf("%d\n",ans);
      //  if(flag) puts("Yes"); else puts("No");
    }
    return 0;
}

B:就是有n个人,m个食物。每个食物属于第a[i]类,每个人只能吃同类别的食物,一天吃一个,求最多可以吃多少天。

没看数据范围,上来就二分,还傻乎乎的用优先队列了。。。其实 n m a[i] 范围都是100以内,直接暴力就行了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
const int INF=0x3f3f3f3f;
int n,m;
int a[110];
struct poin
{
    int w,id;
}mp[110];
int cmp(poin a,poin b)
{
    return a.w>b.w;
}
vector<int>G;
int main()
{
    scanf("%d%d",&n,&m);
    int ans=0;
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&a[i]);
        if(!mp[a[i]].id)
        {
            mp[a[i]].id=a[i];
            mp[a[i]].w++;
            ans++;
        }
        else
        {
            mp[a[i]].w++;
        }
    }
    sort(mp+1,mp+101,cmp);
    int sum=0;
    for(int i=1;i<=100;i++)
    {
        int cnt=0;
        for(int j=1;j<=m;j++)
        {
            cnt+=mp[j].w/i;
        }
        //cout<<i<<" "<<cnt<<endl;
        if(cnt<n)break;
        sum=i;
    }
    cout<<sum<<endl;
    return 0;
}

C:给你n个星球,火箭重m吨。给你每个星球的起飞系数a[i]和降落系数b[i]。让你从第一个星球到第n个星球结束最少耗费多少燃料。每到达一个星球,消耗的燃料为(m+此时火箭的燃料重量)/b[i]  。a[i]同理。。。

只需要倒着推,假设最终正好剩余0燃料,那么最后一次起飞消耗的燃料x满足(x+m)/a[n]=x 移项即可得倒推公式。b[i]也一样。

但是这里有个问题:倒着推的话应该先起飞再降落,也就是先a[i]再b[i],我代码里写倒了居然也过了,没挂终测,可能真的与顺序无关?

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=20010;
const long double eps=1e-12;
long double n,m,k;
long double a[maxn],b[maxn],sum[maxn];
long double ans,ct,cnt,tmp,flag;
char s[maxn];
int main()
{
    while(cin>>n>>m)
    {
        flag=1;
        for(int i=0;i<n;i++){
           cin>>a[i];
        }
        for(int i=0;i<n;i++){
           cin>>b[i];
        }
        int i=n-1;
        long double x=0,y=0,ans=1.0;
        while(i>=0)
        {
            if(a[i]==1||b[i]==1) ans=-1.0;
            y=(m+x)/(b[i]-1.0);
            x+=y;
            y=(m+x)/(a[i]-1.0);
            x+=y;
            i--;
        }
        if(ans<0) puts("-1");
       else cout<<fixed<<setprecision(12)<<x<<endl;
      //  if(flag) puts("Yes"); else puts("No");
    }
    return 0;
}

D:这个互动题真是坑。。。第一次见。。。出了个ILE错误。。。有待研究。。。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=20010;
int n,m,k,ans;
int a[maxn];
int main()
{
    scanf("%d%d",&m,&n);
    {
        int flag=1;
        for(int i=0;i<n;i++)
        {
        printf("%d\n",i+1);
        fflush(stdout);
        scanf("%d",&k);
        if(k==1) a[i]=-1;
        else if(k==-1)a[i]=1;
        if(k==0) return 0;
        }
        int l=n,r=m;
        int stp=0;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            printf("%d\n",mid);
            fflush(stdout);
            scanf("%d",&k);
            if(k==0)return 0;
            k*=a[stp];
            stp=(stp+1)%n;
            if(k==-1)l=mid+1;
            else r=mid;
        }
       //cout<<fixed<<setprecision(12)<<x<<endl;
      //  if(flag) puts("Yes"); else puts("No");
    }
    return 0;
}

E:给你n种纸币,求这n种纸币的任意组合mod m意义下,能组成多少0~m-1的数。

这就是离散数学的基本知识啊。。。n个纸币和m的gcd就是最小生成元,这个元的所有倍数小于m的数就是能生成的数。。。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=20010;
const long double eps=1e-12;
int n,m,k,ans;
int a;
int gcd(int x,int y)
{return y==0?x:gcd(y,x%y);}
int main()
{
    scanf("%d%d",&n,&m);
    {
        int flag=1;
        ans=m;
        for(int i=0;i<n;i++)
        {scanf("%d",&a);
        ans=gcd(ans,a);
        }
        printf("%d\n",m/ans);
        for(int i=0;i<m;i+=ans)
        printf("%d%c",i,i+ans<m?' ':'\n');
       //cout<<fixed<<setprecision(12)<<x<<endl;
      //  if(flag) puts("Yes"); else puts("No");
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值