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 }

你可能感兴趣的:(USACO)