USACO 3.3 Camelot(BFS+乱搞)
做的我好郁闷啊。。。卡到死了,想了一个暴力方法,枚举骑士和国王相遇的点,再枚举所有的骑士相遇的点。这样复杂度基本上上亿了,然后卡了几天,看了看题解,枚举国王和骑士的相遇的时候只需要枚举国王周围的几个点就行了。。。然后原来写的代码,各种BUG啊。。。各种调试,各种提交,各种错误n,m看错各种变量写错,实在是无语,最后终于检查不出错误了,提交还是挂了。。。找AC代码 换函数。。。最后还是没检查出那里错了,换了跟AC代码的写法,终于过了。。。这题真心不想做第二遍了。。。
1 /* 2 ID: cuizhe 3 LANG: C++ 4 TASK: camelot 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <cmath> 9 #include <queue> 10 using namespace std; 11 #define INF 0x3f3f3f3f 12 int o[51][51],na[31][31][31][31],n,m,num; 13 int a[8] = {1,1,-1,-1,2,2,-2,-2}; 14 int b[8] = {2,-2,2,-2,1,-1,1,-1}; 15 int r[1001],c[1001]; 16 void bfs(int x,int y)//预处理所有的可以走的最短路 17 { 18 int quer[5001],quec[5001]; 19 int str,end,i,j,k; 20 memset(o,-1,sizeof(o)); 21 quer[1] = x,quec[1] = y; 22 o[x][y] = 0; 23 str = end = 1; 24 while(str <= end) 25 { 26 j = 1; 27 for(i = str; i <= end; i ++) 28 { 29 for(k = 0; k <= 7; k ++) 30 { 31 if(quer[i]+a[k]<=m&&quer[i]+a[k]>=1&&quec[i]+b[k]>=1&&quec[i]+b[k]<=n&&o[quer[i]+a[k]][quec[i]+b[k]] == -1) 32 { 33 o[quer[i]+a[k]][quec[i]+b[k]] = o[quer[i]][quec[i]]+1; 34 quer[end+j] = quer[i] + a[k]; 35 quec[end+j] = quec[i] + b[k]; 36 j ++; 37 } 38 } 39 } 40 str = end + 1; 41 end = end + j - 1; 42 } 43 for(i = 1; i <= m; i ++) 44 { 45 for(j = 1; j <= n; j ++) 46 { 47 if(na[x][y][i][j] > o[i][j]&&o[i][j] != -1) 48 na[x][y][i][j] = o[i][j]; 49 } 50 } 51 } 52 int Abs(int x) 53 { 54 if(x < 0) 55 return -x; 56 else 57 return x; 58 } 59 int Max(int a,int b) 60 { 61 return a > b ? a:b; 62 } 63 int ac(int x,int y)//枚举国王在(x,y)和骑士相遇,本来没有写成函数的。。。 64 { 65 int i,j,k,sum = 0,ans; 66 for(k = 2; k <= num; k ++) 67 { 68 if(na[r[k]][c[k]][x][y] == INF)//这里注意越界。。。 69 return INF; 70 sum += na[r[k]][c[k]][x][y]; 71 } 72 ans = sum + Max(Abs(r[1]-x),Abs(c[1]-y)); 73 for(i = 2; i <= num; i ++) 74 { 75 for(j = Max(1,r[1]-2); j <= m&&j <= r[1]+2; j ++) 76 { 77 for(k = Max(1,c[1]-2); k <= n&&k <= c[1]+2;k ++) 78 { 79 ans=min(ans,sum-na[r[i]][c[i]][x][y]+na[r[i]][c[i]][j][k]+na[j][k][x][y]+max(Abs(r[1]-j),Abs(c[1]-k))); 80 } 81 } 82 } 83 return ans; 84 } 85 int main() 86 { 87 int i,j,k,u,ans; 88 char p[1001][3]; 89 freopen("camelot.in","r",stdin); 90 freopen("camelot.out","w",stdout); 91 scanf("%d%d",&n,&m);//其实n,m我弄反了。。。 92 i = 1; 93 while(scanf("%s %d",p[i],&c[i])!=EOF) 94 { 95 r[i] = p[i][0]-'A'+1; 96 i ++; 97 } 98 num = i-1; 99 if(num == 0) 100 { 101 printf("0\n"); 102 return 0; 103 } 104 for(i = 1; i <= m; i ++) 105 { 106 for(j = 1; j <= n; j ++) 107 { 108 for(k = 1; k <= m; k ++) 109 { 110 for(u = 1; u <= n; u ++) 111 na[i][j][k][u] = INF; 112 } 113 na[i][j][i][j] = 0; 114 } 115 } 116 for(i = 1; i <= m; i ++) 117 { 118 for(j = 1; j <= n; j ++) 119 { 120 bfs(i,j); 121 } 122 } 123 ans = INF; 124 for(i = 1; i <= m; i ++) 125 { 126 for(j = 1; j <= n; j ++) 127 { 128 ans=min(ans,ac(i,j)); 129 } 130 } 131 if(ans == INF) 132 printf("0\n"); 133 else 134 printf("%d\n",ans); 135 return 0; 136 }