hdu 1847
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int dp[1003];
int main()
{
int p[30];
p[0]=1;
for(int i=1;i<20;i++){
p[i]=p[i-1]<<1;
}
memset(dp,0,sizeof(dp));
dp[0]=0;dp[1]=1;
dp[2]=1;
for(int i=3;i<1003;i++){
for(int j=0;j<20;j++){
if(p[j]<=i){
if(dp[i-p[j]]==0)dp[i]=1;
}
}
}
int n;
while(scanf("%d",&n)!=EOF){
dp[n]==0?printf("Cici\n"):printf("Kiki\n");
}
return 0;
}
hdu 1848
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
using namespace std;
int sg[1045];
int f[100];
void grundy(){
sg[0]=0;
for(int j=1;j<=1000;j++){
set<int >s;
for(int i=1;i<20;i++){
if(f[i]<=j)s.insert(sg[j-f[i]]);
}
int g=0;
while(s.count(g))g++;
sg[j]=g;
}
}
int main()
{
f[0]=1;
f[1]=1;
f[2]=2;
for(int i=3;i<20;i++){
f[i]=f[i-1]+f[i-2];
}
grundy();
int n,m,p;
while(~scanf("%d%d%d",&n,&m,&p)){
if(!n&&!m&&!p)break;
string ans=(sg[n]^sg[m]^sg[p])==0?"Nacci":"Fibo";
cout<<ans<<endl;
}
return 0;
}
hdu 5724
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <set>
#include <cstring>
using namespace std;
int sg[1100000];
int s[30];
void grundy(){
sg[0]=0;
for(int i=1;i<(1<<20);i++){
memset(s,0,sizeof(s));
for(int j=0;j<20;j++){
if(i&(1<<j)){
for(int k=j;k>=0;k--){
if(!(i&(1<<k))){
s[sg[( (i^(1<<j) )|(1<<k))]]=1;
break;
}
}
}
}
for(int j=0;j<30;j++){
if(s[j]==0){
sg[i]=j;break;
}
}
}
}
int main()
{
grundy();
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
int ans=0;
for(int i=0;i<n;i++){
int m;
scanf("%d",&m);
int tmp=0;
for(int j=0;j<m;j++){
int z;
scanf("%d",&z);
tmp|=1<<(20-z);
}
ans^=sg[tmp];
}
if(ans)printf("YES\n");
else printf("NO\n");
}
return 0;
}
hdu 1809
这道题目我一定要好好吐槽一下,二维char数组表示成一维string,用来表示状态,然后求sg函数值用记忆化搜索,然后就一直WA,心好累差点怀疑人生,QAQ。后来发现记忆化搜索代码加上 if(vis[str])return sg[str]; 就WA,所以肯定这里出问题,后来一想,这种状态表示有毒,例如5x4与4x5的矩阵显然不同,但是展开成一维string时显然可以得到相同string,所以二维展一维时除了内容,还要加上R,C两个参数。可是这样就要用结构体,想想acm中处理字符串的技巧,其实在二维数组表示成string时,在末尾加上一个区别的符号就行了。这样就可以写最正宗的记忆化搜索了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cstring>
using namespace std;
char g[55][55];
map<string,int>sg;
map<string,int>vis;
string ss;
int R,C;
string tostr(){
ss="";
for(int i=0;i<R;i++){
ss+=g[i];
ss+='*';
}
return ss;
}
int grundy(){
string str=tostr();//cout<<str<<endl;
if(vis[str])return sg[str];
int s[100];
memset(s,0,sizeof(s));
for(int i=1;i<R;i++){
for(int j=1;j<C;j++){
if(g[i][j]=='0'&&g[i-1][j]=='0'&&g[i][j-1]=='0'&&g[i-1][j-1]=='0'){
g[i][j]='1';g[i-1][j]='1';g[i][j-1]='1';g[i-1][j-1]='1';
s[grundy()]=1;
g[i][j]='0';g[i-1][j]='0';g[i][j-1]='0';g[i-1][j-1]='0';
}
}
}
int k=0;
while(s[k])k++;
vis[str]=1;
sg[str]=k;
return k;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
int ans=0;
for(int i=0;i<n;i++){
scanf("%d%d",&R,&C);
for(int j=0;j<R;j++)scanf("%s",g[j]);
ans^=grundy();
}
printf("%s\n",ans?"Yes":"No");
}
return 0;
}