Codeforces Round #427 (Div. 2) [ C. Star sky ] [ D. Palindromic characteristics ] [ E. The penguin's game ]
本来准备好好打一场的,然而无奈腹痛只能带星号参加 (我才不是怕被打爆呢!)
PROBLEM C - Star sky
题
OvO http://codeforces.com/contest/835/problem/C
835C
解
由于题目中给的c很小,可以对应每种亮度分别保存(c+1)个矩阵
然后初始化一下求前缀矩阵
每次询问就可以O(c)求出答案
(Accepted)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int M=144;
const int MM=100;
int mp[M][M][20];
int pre[M][M][20];
int n,q,c;
int ans;
void init()
{
int i,j,k;
memset(pre,0,sizeof(pre));
for(i=1;i<=MM;i++)
for(j=1;j<=MM;j++)
for(k=0;k<=c;k++)
pre[i][j][k]=pre[i-1][j][k]+pre[i][j-1][k]-pre[i-1][j-1][k]+mp[i][j][k];
}
int main()
{
int chg,tmp,i,j,x,y,z,x1,y1,x2,y2,t;
cin>>n>>q>>c;
memset(mp,0,sizeof(mp));
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&z);
mp[x][y][z]++;
}
init();
while(q--)
{
scanf("%d%d%d%d%d",&t,&x1,&y1,&x2,&y2);
ans=0;
for(i=0;i<=c;i++)
{
chg=(i+t)%(c+1);
tmp=pre[x2][y2][i]-pre[x1-1][y2][i]-pre[x2][y1-1][i]+pre[x1-1][y1-1][i];
ans+=tmp*chg;
}
cout<<ans<<endl;
}
return 0;
}
PROBLEM D - Palindromic characteristics
题
OWO http://codeforces.com/contest/835/problem/D
835D
解
对每两点做字符串哈希,然后搜索加记忆化(每搜索一段到一段合法的继续搜左右两边,递归,得到该段的类型,并且用类型来标记该段已经搜过)
这样搜索的时间是O(n*n),然后O(1)判断哈希值是否相等,是的话就把对应计数值+1
pretest能过,最后会不会挂掉就看我取的模了(趁终测还没结束赶紧睡觉~☆)(没挂嘿嘿嘿)
(Accepted)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
const int M=5022;
const int bas=14123;
int ans[M];
char s[M];
int num[M];
int n;
unsigned hsh[M][M];
int flag[M][M];
void init()
{
int i,j;
n=strlen(s+1);
for(i=1;i<=n;i++)
{
if(s[i]>='a')
num[i]=s[i]-'a';
else
num[i]=s[i]-'A'+26;
}
memset(ans,0,sizeof(ans));
memset(flag,-1,sizeof(flag));
for(i=1;i<=n;i++)
{
hsh[i][i]=num[i];
for(j=i+1;j<=n;j++)
hsh[i][j]=hsh[i][j-1]*bas+num[j];
for(j=i-1;j>=1;j--)
hsh[i][j]=hsh[i][j+1]*bas+num[j];
}
}
bool fj(int a,int b,int c,int d)
{
return true;
int i,j;
for(i=a,j=d;i<=b;i++,j--)
if(num[i]!=num[j])
return false;
return true;
}
int check(int a,int d)
{
if(a==d)
{
flag[a][d]=1;
return 1;
}
int tmp=(d-a+1)/2;
int b,c;
b=a+tmp-1; c=d-tmp+1;
// cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<hsh[a][b]<<' '<<hsh[d][c]<<endl;
if(hsh[a][b]==hsh[d][c] && fj(a,b,c,d))
{
int flag0,flag1,flag2;
if(flag[a][b]!=-1)
flag1=flag[a][b];
else
{
flag1=check(a,b);
flag[a][b]=flag1;
ans[flag1]++;
}
if(flag[c][d]!=-1)
flag2=flag[c][d];
else
{
flag2=check(c,d);
flag[c][d]=flag2;
ans[flag2]++;
}
flag0=min(flag1,flag2);
return flag0+1;
}
else
{
flag[a][d]=0;
return 0;
}
}
void solve()
{
int i,j,a,b,c,d,len,tmp;
for(i=1;i<=n;i++)
{
for(j=i;2*j-i<=n;j++)
{
if(2*j-i<=n)
{
a=i; d=2*j-i; len=d-a+1;
if(flag[a][d]==-1)
{
tmp=check(a,d);
flag[a][d]=tmp;
ans[tmp]++;
}
}
if(2*j-i+1<=n)
{
a=i; d=2*j-i+1; len=d-a+1;
if(flag[a][d]==-1)
{
tmp=check(a,d);
flag[a][d]=tmp;
ans[tmp]++;
}
}
}
}
for(i=n;i>=1;i--)
ans[i]+=ans[i+1];
for(i=1;i<=n;i++)
{
if(i-1) printf(" ");
printf("%d",ans[i]);
}
printf("\n");
}
int main()
{
int i,j;
scanf("%s",s+1);
init();
solve();
return 0;
}
一结束我就写了题解 怎么会有我这么勤奋的人呢 我真是太了不起了~☆
PROBLEM E - The penguin's game
题
OwO http://codeforces.com/contest/835/problem/E
835E
解
设要不同的2个点为p,q
1. n的范围为1000,所以最多有10位。所以可以枚举每一位,对该为为1的数字输出,这样可以知道p,q哪些位数不同。(至多10次输出)
2. p,q不同的位的数量至少为1。所以可以随便选取一位,然后,选出该位为1的数字,放入集合中,则这个集合中最多只有1个特殊点(设其为p),所以可以二分区间寻找改p(至多9次输出)
3. 找到p点之后,根据第1步中得到的p和q中各位的关系,得到q
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int N=33;
const int M=1111;
int n,x,y;
int dif[N],chs;
int se[N][M],lse[N];
int rep;
void ask(int len,int s[])
{
printf("? %d",len);
for(int i=1;i<=len;i++)
printf(" %d",s[i]);
printf("\n");
fflush(stdout);
scanf("%d",&rep);
}
void output(int ans1,int ans2)
{
printf("! %d %d\n",ans1,ans2);
fflush(stdout);
}
void init()
{
int i,j,mdl;
memset(lse,0,sizeof(lse));
for(i=1;i<=n;i++)
{
for(j=0;j<10;j++)
{
mdl=(1<<j);
if(i&mdl)
se[j][++lse[j]]=i;
}
}
chs=-1;
memset(dif,0,sizeof(dif));
for(i=0;i<10;i++)
if(lse[i]!=0)
{
ask(lse[i],se[i]);
if(rep!=0 && rep!=x)
{
dif[i]=1;
if(chs==-1)
chs=i;
}
}
}
void solve()
{
int ans1,ans2;
int s[M],ls;
int i,j,tmp;
ls=0;
for(i=1;i<=n;i++)
if(i&(1<<chs))
s[++ls]=i;
int li,ri,mid;
// for(i=1;i<=ls;i++)
// cout<<s[i]<<' ';
// cout<<endl;
li=1; ri=ls;
while(li!=ri)
{
mid=(li+ri)>>1;
ask((mid-li+1),s+li-1);
if(rep==0 || rep==x)
li=mid+1;
else
ri=mid;
}
ans1=s[li];
ans2=ans1^(1<<chs);
for(i=0;i<10;i++)
if(i!=chs && dif[i]==1)
ans2^=(1<<i);
if(ans1>ans2) swap(ans1,ans2);
output(ans1,ans2);
}
int main()
{
cin>>n>>x>>y;
init();
solve();
return 0;
}

浙公网安备 33010602011771号