您的位置:首页 > 其它

Codeforces #355 div.2

2016-06-02 16:30 288 查看
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上熬夜打的第二场比赛,一直处于减分状态,涨分的日子什么时候才能到阿~~~

永远都不要给自己找借口!,自己的不满说到底都是自己的不足造成的,还是刷题,补题吧~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces