题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1061
题意:给定8*8的棋盘上8个皇后。挪动最少的步数使得不互相攻击?
思路:首先预处理求出所有的合法放法(就是这里一开始想了好久没想出来)。然后对于每个测试数据,枚举每一种合法放法。。。枚举的时候记忆化搜索和直接BFS都行,前一种快点。。
1 //记忆化搜索 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #define min(x,y) ((x)<(y)?(x):(y)) 6 using namespace std; 7 8 struct node 9 { 10 int x[10],y[10]; 11 }; 12 13 node ans[1000],p; 14 int sum; 15 int C,num=0; 16 char s[10][10]; 17 18 int abs(int x) 19 { 20 return x>0?x:-x; 21 } 22 23 inline int OK(int x,int y,node a,int n) 24 { 25 int i; 26 for(i=1;i<=n;i++) if(a.y[i]==y||abs(a.x[i]-x)==abs(a.y[i]-y)) 27 return 0; 28 return 1; 29 } 30 31 void DFS(int dep,node &a) 32 { 33 if(dep==9) 34 { 35 ans[++sum]=a; 36 return; 37 } 38 int i; 39 for(i=1;i<=8;i++) if(OK(dep,i,a,dep-1)) 40 { 41 a.x[dep]=dep; 42 a.y[dep]=i; 43 DFS(dep+1,a); 44 } 45 } 46 47 void init() 48 { 49 sum=0; 50 node a; 51 DFS(1,a); 52 } 53 54 const int INF=1000000000; 55 int f[10][300]; 56 57 inline int get(node a,int t1,node b,int t2) 58 { 59 int x1=a.x[t1],y1=a.y[t1]; 60 int x2=b.x[t2],y2=b.y[t2]; 61 if(x1==x2&&y1==y2) return 0; 62 if(x1==x2||y1==y2||abs(x1-x2)==abs(y1-y2)) return 1; 63 return 2; 64 } 65 66 int DFS1(int u,int st,node a) 67 { 68 if(u==8) return 0; 69 if(f[u][st]!=-1) return f[u][st]; 70 int i,t=INF; 71 for(i=0;i<8;i++) if(0==(st&(1<<i))) 72 t=min(t,get(p,u+1,a,i+1)+DFS1(u+1,st|(1<<i),a)); 73 return f[u][st]=t; 74 } 75 76 int deal() 77 { 78 int temp=INF,i; 79 for(i=1;i<=sum;i++) 80 { 81 memset(f,-1,sizeof(f)); 82 temp=min(temp,DFS1(0,0,ans[i])); 83 } 84 return temp; 85 } 86 87 int main() 88 { 89 init(); 90 for(scanf("%d",&C);C--;) 91 { 92 int i,j,k=0; 93 for(i=1;i<=8;i++) 94 { 95 scanf("%s",s[i]+1); 96 for(j=1;j<=8;j++) if(s[i][j]=='q') 97 { 98 p.x[++k]=i; 99 p.y[k]=j; 100 } 101 } 102 printf("Case %d: %d\n",++num,deal()); 103 } 104 return 0; 105 } 106 107 //直接BFS 108 #include <iostream> 109 #include <cstdio> 110 #include <cstring> 111 #include <queue> 112 #define min(x,y) ((x)<(y)?(x):(y)) 113 using namespace std; 114 115 struct node 116 { 117 int x[10],y[10]; 118 }; 119 120 node ans[1000],p; 121 int sum; 122 int C,num=0; 123 char s[10][10]; 124 125 int abs(int x) 126 { 127 return x>0?x:-x; 128 } 129 130 inline int OK(int x,int y,node a,int n) 131 { 132 int i; 133 for(i=1;i<=n;i++) if(a.y[i]==y||abs(a.x[i]-x)==abs(a.y[i]-y)) 134 return 0; 135 return 1; 136 } 137 138 void DFS(int dep,node &a) 139 { 140 if(dep==9) 141 { 142 ans[++sum]=a; 143 return; 144 } 145 int i; 146 for(i=1;i<=8;i++) if(OK(dep,i,a,dep-1)) 147 { 148 a.x[dep]=dep; 149 a.y[dep]=i; 150 DFS(dep+1,a); 151 } 152 } 153 154 void init() 155 { 156 sum=0; 157 node a; 158 DFS(1,a); 159 } 160 161 162 163 inline int get(node a,int t1,node b,int t2) 164 { 165 int x1=a.x[t1],y1=a.y[t1]; 166 int x2=b.x[t2],y2=b.y[t2]; 167 if(x1==x2&&y1==y2) return 0; 168 if(x1==x2||y1==y2||abs(x1-x2)==abs(y1-y2)) return 1; 169 return 2; 170 } 171 172 const int INF=1000000000; 173 int f[66000],visit[66000]; 174 175 int cal(node a,node b) 176 { 177 int k,aa,bb,k0,aa0,bb0,i,j,cost; 178 queue<int> Q; 179 memset(f,-1,sizeof(f)); 180 memset(visit,0,sizeof(visit)); 181 f[255]=0; 182 visit[255]=1; 183 Q.push(255); 184 while(!Q.empty()) 185 { 186 k=Q.front(); 187 Q.pop(); 188 visit[k]=0; 189 aa=k>>8; 190 bb=k&255; 191 for(i=0;i<8;i++) if(bb&(1<<i)) 192 { 193 for(j=0;j<8;j++) if(0==(aa&(1<<j))) 194 { 195 aa0=aa^(1<<j); 196 bb0=bb^(1<<i); 197 k0=(aa0<<8)+bb0; 198 cost=get(b,i+1,a,j+1); 199 if(f[k0]==-1||f[k0]>f[k]+cost) 200 { 201 f[k0]=f[k]+cost; 202 if(!visit[k0]) 203 { 204 Q.push(k0); 205 visit[k0]=1; 206 } 207 } 208 } 209 break; 210 } 211 } 212 return f[255<<8]; 213 } 214 215 int deal() 216 { 217 int temp=INF,i; 218 for(i=1;i<=sum;i++) 219 { 220 memset(f,-1,sizeof(f)); 221 temp=min(temp,cal(ans[i],p)); 222 } 223 return temp; 224 } 225 226 int main() 227 { 228 init(); 229 for(scanf("%d",&C);C--;) 230 { 231 int i,j,k=0; 232 for(i=1;i<=8;i++) 233 { 234 scanf("%s",s[i]+1); 235 for(j=1;j<=8;j++) if(s[i][j]=='q') 236 { 237 p.x[++k]=i; 238 p.y[k]=j; 239 } 240 } 241 printf("Case %d: %d\n",++num,deal()); 242 } 243 return 0; 244 }