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 }
posted @ 2012-11-27 13:41  Naix_x  阅读(176)  评论(0编辑  收藏  举报