http://codeforces.com/contest/1102
这场比赛的A题是个小思维题,连续的四个数x,x+1,x+2,x+3,则x+(x+3)=(x+1)+(x+2),所以从n开始考虑,每四个数恰好分配,最后只会剩下n%4个数,只需要简单算一下判断一下就ok,
B题略坑。。比赛的时候题意读了很久都读不懂。就先做C了。快一个小时了才又给的题意解释,勉强算是明白了,感觉倒不是难题,然而,,B题莫名又T了一发,,RE了两发,。,改了感觉并不重要的地方,换换语言,感觉代码本质没变,,然后A了,,,也真是佩服自己敢交的勇气,,,超怕被hack。。。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,k,ok,vis[5055],ans[5055];
struct AA
{
int x,rt;
bool operator<(const AA &aa)const
{
return x<aa.x;
}
}pos[5055];
int main()
{//cout<<"!"<<endl;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
pos[i].rt=i;
scanf("%d",&pos[i].x);
if(++vis[pos[i].x]>k) ok=1;
}
if(ok==1)
{
printf("NO\n");
return 0;
}
printf("YES\n");
sort(pos+1,pos+n+1);
for(int i=1;i<=n;i++)
{
if((i%k)==0)
ans[pos[i].rt]=k;
else ans[pos[i].rt]=(i%k);
}
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
printf("\n");
return 0;
/*
if(ok)
else
cout<<"NO"<<endl;
*/
}
C题小思维,跟x与y的大小有关,因为进行次数相当于无限多次,所以x>y的时候一定所有都碎了,x<=y的时候,x只能破坏<=x的门,不然y能救回来,,而且在x破坏<=x的门的后,y可以修复一扇<=x的门,这样就能多保住一扇。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,x,y,m,ok,a[100005],ans;
int main()
{
scanf("%d%d%d",&n,&x,&y);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
if(x>y)
{
cout<<n<<endl;
return 0;
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
if(a[i]<=x) ans++;
else break;
}
int i;
for(i=1;i<ans;i++)
{
a[ans]+=y;
if(a[ans]>x) ans--;
}
cout<<ans<<endl;
/*
if(ok)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
*/
}
D题也比较简单,就是先算一下0,1,2的数量,多于平均数t一定得转化成少于平均数的数,从前往后遍历,0的前t个0保持不变,然后后面若还有多余的0,就看看1够不够,变成1,1够了,就只能变成2,
1就是先看有没有多余的需要变成0的,然后安排1本身,最后再有多余的变成2,
2就是,2若多余,若0少,先变成0,然后1若少,变成1,最后保留为自己。
代码:
就暴力写 了,没注意美观了,,,还因为每加else if的elseWA了一发,,,也怪自己没试样例。。
#include<bits/stdc++.h>
using namespace std;
int n,a[10],t,b[10];
string s;
int main()
{//cout<<"!"<<endl;
cin>>n>>s;
t=n/3;
for(int i=0;i<n;i++)
{
a[s[i]-'0']++;
}
for(int i=0;i<n;i++)
{
if(s[i]=='0')
{
if(b[0]<t) {b[0]++;continue;}
else if(b[0]>=t)
{
if(a[1]<t)
{//cout<<i<<" "<<a[1]<<" "<<a[2]<<" "<<t<<"!"<<endl;
a[1]++;a[0]--;
b[1]++;
s[i]='1';
}
else
{
a[2]++;a[0]--;
b[2]++;
s[i]='2';
}
}
}
else if(s[i]=='1')
{
if(a[1]>t&&a[0]<t)
{
s[i]='0';
a[0]++;
b[0]++;
a[1]--;
continue;
}
if(b[1]<t) {b[1]++;continue;}
else if(b[1]>=t)
{
a[2]++;a[1]--;
b[2]++;
s[i]='2';
}
}
else if(s[i]=='2')
{
if(a[2]>t&&a[0]<t)
{
a[0]++;a[2]--;
b[0]++;
s[i]='0';
continue;
}
else if(a[2]>t&&a[1]<t)
{
a[1]++;a[2]--;
b[1]++;
s[i]='1';
continue;
}
if(b[2]<t) {b[2]++; continue;}
}
}
cout<<s<<endl;
/*
if(ok)
else
cout<<"NO"<<endl;
*/
}
/*
*/
最后拼了几分钟写了个E题,又是快速幂粗心。。。没考虑0次方的情况。导致快速幂里死循环了,,T了一发。。
思路倒是也不难,就是找间断点,可以选择是否变化的点的个数,然后2的ans次方。。。就完了,倒不是难题,
思路:根据题意要求b又要递增,又要与a对应的相等的点相等,那么a中相等的点及其中间夹的所有点的值在b中都相等。与中间点a值相等的点在b中也要相同,,,所以就是循环下去,一直结束,就是一个间断点,再就是注意,最后一个数后面不能是间断点就可以了,,,
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mod 998244353
int n,a[500005];
ll ans;
ll POW(ll aa,ll bb)
{
if(bb==0) return 1;
if(bb==1) return aa%mod;
if(bb%2) return POW(aa*aa%mod,bb/2)*aa%mod;
else return POW(aa*aa%mod,bb/2);
}
int main()
{ //cout<<POW(2,200005)<<endl;
scanf("%d",&n);
map<int,int>ma;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
ma[a[i]]=i;
}
for(int i=1;i<n;)
{
for(int j=i;j<=i;j++)
{
i=max(i,ma[a[j]]);
}
if(i<n)
{
ans++;
}
i++;
}
ans=POW(2,ans);
printf("%I64d\n",ans%mod);
}