Codeforces #355 div.2

B.

题意:输入n,h,k,分别表示n个土豆,规定能放入压土豆机的最大高度,k表示每次压土豆机压碎土豆的高度。问机器最少需要压几次?

思路:我直接想到的这就是一个模拟的过程,trick点就是n是1e5,h是1e9,所以压的次数会爆int.

被×了 23333.

#include<bits/stdc++.h>
using namespace std;
int a[100005];
int main()
{
    int n,h,k,now=0;
    long long t=0;
    scanf("%d%d%d",&n,&h,&k);
    for(int i=0; i<n; i++)
        scanf("%d",&a[i]);
    for(int i=0; i<n-1; i++)
    {
        //将每次循环到的a[i]视为目前压土豆机里的土豆高度.
        if(!a[i])continue;  //这里其实也可有可无。
        if(a[i]+a[i+1]>h)
        {
            while(a[i]+a[i+1]>h)     //最多循环两次。(a[i]/k得到的余数必定小于k)
            {
                if(a[i]<k)
                {
                    t++;
                    a[i]=0;
                }
                t+=a[i]/k;             //如果加上a[i+1]>h,那么就先对a[i]进行处理。
                a[i]=a[i]%k;
                if(!a[i])break;  //因为a[i]<=h,所以可有可无
            }
        }
        if(a[i]+a[i+1]<=h)
        {
            t+=(a[i]+a[i+1])/k;
            a[i+1]=(a[i]+a[i+1])%k;       //如果有剩余的土豆高度不足k,那么就转移到下一次进行压碎。
        }
    }
    if(a[n-1]%k)
        t+=a[n-1]/k+1;
    else t+=a[n-1]/k;
    printf("%lld\n",t);
}


上面自己写的代码太繁琐。

下面是简洁的,

#include<bits/stdc++.h>
int main()
{
    int n,h,k,h1,now=0; //now表示目前处理器内土豆累积的高度。
    long long ans=0;
    scanf("%d%d%d",&n,&h,&k);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&h1);
        if(now+h1>h) //目前土豆累积的高度加上将要放入的土豆高度如果超过h,那么之前土豆累积的高度必须先清0;
        {
            ans++;
            now=0;
        }
        now+=h1;
        ans+=now/k;
        now=now%k;
    }
    if(now)  //now是必定小于k的.
        ans++;
    printf("%lld\n",ans);
}


C.

题意:给一个字符串s,求某两个与s相同长度的字符串进行&运算后,可以得到字符串s。0-9,A-Z,a-z,-,_分别表示从0-63的64进制。

思路:先考虑一个字母的时候,那么如果两个字母进行&运算后要得到该字母,因为是64进制,所以O(64^2)的复杂度预处理一下,那么长度|s|的s字符串只要逐位相乘%mod.

还有一种做法就是观察&运算,因为&运算的结果是只有4种的(0&1=0,0&0=0,1&0=0,1&1=1),所以对于一个字母的64进制,例如样例一,Z的64进制为35,二进制为(100011),那么每位能够得到0的可能为3种,

那么只要数每一个字母二进制低6位的0的个数num,因为最大的数字63是低6位的,每个字母的可能性就是3^num。

第一种做法:

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int t[200],pre[200];
char s[100005];
int main()
{
   memset(t,0,sizeof(t));
   memset(pre,0,sizeof(pre));
   for(int i=0;i<10;i++)
    t['0'+i]=i;
   for(int i=0;i<26;i++)
   {t['a'+i]=36+i;
    t['A'+i]=10+i;
   }
   t['-']=62;
   t['_']=63;
   for(int i=0;i<64;i++)
    for(int j=0;j<64;j++)
    pre[i&j]++;

   scanf("%s",s);
   long long  ans=1;
   for(int i=0;i<strlen(s);i++)
    ans=ans*pre[t[s[i]]]%mod;
    printf("%lld\n",ans);
}


第二种做法:

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int t[200],pre[200];
char s[100005];
int main()
{
    memset(t,0,sizeof(t));
   memset(pre,0,sizeof(pre));
   for(int i=0;i<10;i++)
    t['0'+i]=i;
   for(int i=0;i<26;i++)
   {t['a'+i]=36+i;
    t['A'+i]=10+i;
   }
   t['-']=62;
   t['_']=63;
   scanf("%s",s);
   long long ans=1;
   for(int i=0;i<strlen(s);i++)
   {
       int now=t[s[i]];
       for(int j=0;j<6;j++)
           if(!((now>>j)&1))
        ans=ans*3%mod;
   }
   printf("%lld\n",ans);
}



















































在Codeforces上熬夜打的第二场比赛,一直处于减分状态,涨分的日子什么时候才能到阿~~~

永远都不要给自己找借口!,自己的不满说到底都是自己的不足造成的,还是刷题,补题吧~~



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章