0x28 IDA*
一个早上做完了我真牛B
就是A*用于DFS啊,现在我才发现迭代加深真是个好东西。
poj3460 %了%了我们的目标是把它的顺序变对,那么第i个位置的值+1是要等于第i+1个位置的值的。对于一个操作,最多就能修正3个位置对应。这题我多迭代了一层时间就跑了多10倍有点恐怖
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,ans,c[20]; int count() { int ret=0; for(int i=0;i<n;i++) if(c[i]+1!=c[i+1])ret++; if(c[n]!=n)ret++; return ret; } int u[20]; void change(int l,int r,int be) { for(int i=1;i<=n;i++)u[i]=c[i]; for(int i=l;i<=r;i++)c[be+i-l]=u[i]; for(int i=1,j=1;i<=n&&j<=n;i++,j++) { if(i==be)i=be+r-l+1; if(j==l)j=r+1; c[i]=u[j]; } } bool dfs(int k) { if(count()==0)return true; if(k>=ans)return false; int t[20]; for(int l=1;l<=n;l++) { for(int r=l;r<=n;r++) { for(int be=1;be+r-l<=n;be++) { if(l==be)continue; memcpy(t,c,sizeof(t)); change(l,r,be); int cc=count(); cc=cc%3==0?cc/3:cc/3+1; if(cc+k+1<=ans) { if(dfs(k+1))return true; } memcpy(c,t,sizeof(c)); } } } return false; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n);c[0]=0; for(int i=1;i<=n;i++)scanf("%d",&c[i]); for(ans=0;ans<=5;ans++) { if(dfs(0))break; } if(ans<5)printf("%d\n",ans); else printf("5 or more\n"); } return 0; }
poj2286 这题写的有点丑。。很好想啊,就是看中间有最多有多少个是相等的。英语太烂没看题意结果被No moves needed卡了半小时
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const int u[2][7]={{1,3,7,12,16,21,23}, {2,4,9,13,18,22,24}}; int c[30],ans; char ss[30];int num; int count() { int sa[4];memset(sa,0,sizeof(sa)); sa[c[7]]++;sa[c[8]]++;sa[c[9]]++; sa[c[12]]++;sa[c[13]]++; sa[c[16]]++;sa[c[17]]++;sa[c[18]]++; return 8-max(sa[1],max(sa[2],sa[3])); } void change(int w) { if(w==1) for(int i=0;i<6;i++)swap(c[u[0][i]],c[u[0][i+1]]); else if(w==2) for(int i=0;i<6;i++)swap(c[u[1][i]],c[u[1][i+1]]); else if(w==3) for(int i=11;i>5;i--)swap(c[i],c[i-1]); else if(w==4) for(int i=20;i>14;i--)swap(c[i],c[i-1]); else if(w==5) for(int i=6;i>0;i--)swap(c[u[1][i]],c[u[1][i-1]]); else if(w==6) for(int i=6;i>0;i--)swap(c[u[0][i]],c[u[0][i-1]]); else if(w==7) for(int i=14;i<20;i++)swap(c[i],c[i+1]); else if(w==8) for(int i=5;i<11;i++)swap(c[i],c[i+1]); } bool dfs(int k) { if(count()==0){num=c[7];return true;} if(k>=ans)return false; change(1); if(count()+k+1<=ans) { ss[k+1]='A'; if(dfs(k+1))return true; } change(6); change(2); if(count()+k+1<=ans) { ss[k+1]='B'; if(dfs(k+1))return true; } change(5); change(3); if(count()+k+1<=ans) { ss[k+1]='C'; if(dfs(k+1))return true; } change(8); change(4); if(count()+k+1<=ans) { ss[k+1]='D'; if(dfs(k+1))return true; } change(7); change(5); if(count()+k+1<=ans) { ss[k+1]='E'; if(dfs(k+1))return true; } change(2); change(6); if(count()+k+1<=ans) { ss[k+1]='F'; if(dfs(k+1))return true; } change(1); change(7); if(count()+k+1<=ans) { ss[k+1]='G'; if(dfs(k+1))return true; } change(4); change(8); if(count()+k+1<=ans) { ss[k+1]='H'; if(dfs(k+1))return true; } change(3); return false; } int main() { while(scanf("%d",&c[1])!=EOF) { if(c[1]==0)break; for(int i=2;i<=24;i++)scanf("%d",&c[i]); for(ans=0;;ans++) { if(dfs(0))break; } if(ans==0)printf("No moves needed\n"); else { for(int i=1;i<=ans;i++)printf("%c",ss[i]); printf("\n"); } printf("%d\n",num); } return 0; }
poj1084 表扬一下自己,写完没CE随便调了调就A了。这个一开始想了个很错的做法就是判断每根火柴删除会删除多少矩阵,结果其实删了一个就会对其他有影响。正确的做法是找个矩阵把它全删了,算删了一个,看删多少次。这样预估函数肯定比实际小
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,ans; bool mp[20][20]; bool check_square(int L,int x,int y) { for(int j=y;j<=y+L-1-1;j++) if(mp[2*x-1][j]==false||mp[2*(x+L-1)-1][j]==false)return false; for(int i=x;i<=x+L-1-1;i++) if(mp[2*i][y]==false||mp[2*i][y+L-1]==false)return false; return true; } bool find_square(int &L,int &i,int &j) { for(L=2;L<=n+1;L++) for(i=1;i+L-1<=n+1;i++) for(j=1;j+L-1<=n+1;j++) if(check_square(L,i,j)==true) return true; return false; } bool bp[20][20]; int count() { memcpy(bp,mp,sizeof(bp)); int L,i,j,cnt=0; while(find_square(L,i,j)==true) { for(int v=j;v<=j+L-1-1;v++) { mp[2*i-1][v]=false; mp[2*(i+L-1)-1][v]=false; } for(int u=i;u<=i+L-1-1;u++) { mp[2*u][j]=false; mp[2*u][j+L-1]=false; } cnt++; } memcpy(mp,bp,sizeof(mp)); return cnt; } bool dfs(int k) { if(count()==0)return true; if(k>=ans)return false; int L,i,j; bool zz=find_square(L,i,j); for(int v=j;v<=j+L-1-1;v++) { mp[2*i-1][v]=false; if(count()+k+1<=ans) { if(dfs(k+1))return true; } mp[2*i-1][v]=true; mp[2*(i+L-1)-1][v]=false; if(count()+k+1<=ans) { if(dfs(k+1))return true; } mp[2*(i+L-1)-1][v]=true; } for(int u=i;u<=i+L-1-1;u++) { mp[2*u][j]=false; if(count()+k+1<=ans) { if(dfs(k+1))return true; } mp[2*u][j]=true; mp[2*u][j+L-1]=false; if(count()+k+1<=ans) { if(dfs(k+1))return true; } mp[2*u][j+L-1]=true; } return false; } int main() { int T; scanf("%d",&T); while(T--) { int m; scanf("%d%d",&n,&m); memset(mp,true,sizeof(mp)); for(int i=1;i<=m;i++) { int k; scanf("%d",&k); int mo=(k-1)%(n+n+1); if(mo<n)mp[(k-1)/(n+n+1)*2+1][mo+1]=false; else mp[(k-1)/(n+n+1)*2+2][mo-n+1]=false; } for(ans=0;;ans++) { if(dfs(0))break; } printf("%d\n",ans); } return 0; }
pain and happy in the cruel world.