题目:http://www.nocow.cn/index.php/Translate:USACO/camelot
题目挺好理解的,但是没有清晰的思路,只靠不断的模拟,目前USACO里面,我写过的最长的算法程序。而且还没通过,各种抓狂中……
先插代码,实在没有很好的想法,悲剧啊,难到这就是局限了。欢迎大家给意见
#include <iostream> #include <fstream> #include <math.h> #define ROW 31 #define COLUMN 27 #define SIZE 780 #define LARGE 0X7FFFFFFF #define KNIGHT 800 #define KING 900 using namespace std; struct Position { int r; int c; }; //棋盘 int R,C; int grid[ROW][COLUMN] = {0}; //骑士 Position knight[SIZE]; int knightload[SIZE]; //骑士所走过的路的长度 int kl; int result = LARGE; //国王 Position king; int kingtoknight[SIZE]; //骑士到国王的距离 bool flag = false; Position knightk; //国王到最近骑士的距离 int kntok = LARGE;//国王到最近骑士的距离 //记录遍历路径 Position path[SIZE]; int pl = 0; //初始化整个棋盘 void initGrid() { for (int i=1; i <= R; i++) { for (int j=1; j <= C;j ++) { grid[i][j] = 0; }//end j }//end i grid[king.r][king.c] = KING; for (int i =0; i < kl; i ++ ) { grid[knight[i].r][knight[i].c] = KNIGHT; }//end i } int getKnight(int r,int c) { for (int i=0; i < kl; i ++) { if (knight[i].r == r && knight[i].c == c) { return i; }//end if } return -1; } int main() { ifstream fin("camelot.in"); ofstream fout("camelot.out"); char column; //读入数据 fin >> R >> C; //读入国王 fin >> column >> king.r; king.c = column - 'A' + 1; grid[king.r][king.c] = KING; //读入骑士 while (!fin.eof()) { fin >> column >> knight[kl].r; if (knight[kl].r != 0) { knight[kl].c = column - 'A' + 1; if (grid[knight[kl].r][knight[kl].c] == KING) { //国王其实在同一个位置 grid[knight[kl].r][knight[kl].c] = KNIGHT; flag = true; } else { grid[knight[kl].r][knight[kl].c] = KNIGHT; } kl ++; } }//end while if (kl == 0) { fout << 0 << endl; return 0; } if(!flag) { //广度遍历国王到最短的骑士,按照骑士走法 path[0] = king; pl ++; int klnumber = 0; grid[king.r][king.c] = 0; for (int i=0; i < pl; i ++) { int r = path[i].r; int c = path[i].c; //左斜上 if (r > 1 && c > 2 ) { if (grid[r-1][c-2] == 0) { path[pl].r = r -1; path[pl].c = c -2; grid[r-1][c-2] = grid[r][c] + 1; pl ++; }//end if else if(grid[r-1][c-2] == KNIGHT) { path[pl].r = r -1; path[pl].c = c -2; pl ++; int index = getKnight(r-1,c-2); kingtoknight[index] = grid[r][c] + 1; grid[r-1][c-2] = grid[r][c] + 1; klnumber ++; }//end else if (klnumber == kl) { break; } } //左上 if (r > 2 && c > 1) { if (grid[r-2][c-1] == 0) { path[pl].r = r -2; path[pl].c = c -1; grid[r-2][c-1] = grid[r][c] + 1; pl ++; }//end if else if(grid[r-2][c-1] == KNIGHT) { path[pl].r = r -2; path[pl].c = c -1; pl ++; int index = getKnight(r-2,c-1); kingtoknight[index] = grid[r][c] + 1; grid[r-2][c-1] = grid[r][c] + 1; klnumber ++; }//end else if (klnumber == kl) { break; } } //右上 if (r > 2 && c + 1 <= C) { if (grid[r-2][c+1] == 0) { path[pl].r = r - 2; path[pl].c = c+ 1; grid[r-2][c+1] = grid[r][c] + 1; pl ++; }//end if else if(grid[r-2][c+1] == KNIGHT) { path[pl].r = r - 2; path[pl].c = c+ 1; pl ++; int index = getKnight(r-2,c+1); kingtoknight[index] = grid[r][c] + 1; grid[r-2][c+1] = grid[r][c] + 1; klnumber ++; }//end else if (klnumber == kl) { break; } } //右斜上 if (r > 1 && c + 2 <= C) { if (grid[r-1][c+2] == 0) { path[pl].r = r - 1; path[pl].c = c+ 2; grid[r-1][c+2] = grid[r][c] + 1; pl ++; }//end if else if (grid[r-1][c+2] ==KNIGHT) { path[pl].r = r - 1; path[pl].c = c+ 2; pl ++; int index = getKnight(r-1,c+2); kingtoknight[index] = grid[r][c] + 1; grid[r-1][c+2] = grid[r][c] + 1; klnumber ++; }//end else if (klnumber == kl) { break; } } //右斜下 if (r + 1 <= R && c + 2 <= C) { if (grid[r+1][c+2] == 0) { path[pl].r = r +1; path[pl].c = c+ 2; grid[r+1][c+2] = grid[r][c] + 1; pl ++; }//end if else if(grid[r+1][c+2]==KNIGHT) { path[pl].r = r +1; path[pl].c = c+ 2; pl ++; int index = getKnight(r+1,c+2); kingtoknight[index] = grid[r][c] + 1; grid[r+1][c+2] = grid[r][c] + 1; klnumber ++; }//end else if (klnumber == kl) { break; } } //右下 if (r + 2 <= R && c + 1 <= C) { if (grid[r+2][c+1] == 0) { path[pl].r = r +2; path[pl].c = c+ 1; grid[r+2][c+1] = grid[r][c] + 1; pl ++; }//end if else if(grid[r+2][c+1] == KNIGHT) { path[pl].r = r +2; path[pl].c = c+ 1; pl ++; int index = getKnight(r+2,c+1); kingtoknight[index] = grid[r][c] + 1; grid[r+2][c+1] = grid[r][c] + 1; klnumber ++; }//end else if (klnumber == kl) { break; } } //左下 if (r + 2 <= R && c - 1 >0) { if (grid[r+2][c-1] == 0) { path[pl].r = r +2; path[pl].c = c- 1; grid[r+2][c-1] = grid[r][c] + 1; pl ++; }//end if else if (grid[r+2][c-1] ==KNIGHT) { path[pl].r = r +2; path[pl].c = c- 1; pl ++; int index = getKnight(r+2,c-1); kingtoknight[index] = grid[r][c] + 1; grid[r+2][c-1] = grid[r][c] + 1; klnumber ++; }//end else if (klnumber == kl) { break; } } //左斜下 if (r + 1 <= R && c - 2 >0) { if (grid[r+1][c-2] == 0) { path[pl].r = r +1; path[pl].c = c- 2; grid[r+1][c-2] = grid[r][c] + 1; pl ++; }//end if else if (grid[r+1][c-2] == KNIGHT) { path[pl].r = r +1; path[pl].c = c- 2; pl ++; int index = getKnight(r+1,c-2); kingtoknight[index] = grid[r][c] + 1; grid[r+1][c-2] = grid[r][c] + 1; klnumber ++; }//end else if (klnumber == kl) { break; } } }//end for }//end if !flag //国王到骑士的路径 for (int i=0; i < kl; i ++ ) { int absr = abs(knight[i].r - king.r); int absc = abs(knight[i].c - king.c); int temp = max(absr,absc); if (temp < kntok) { kntok = temp; knightk.r = knight[i].r; knightk.c = knight[i].c; }//end if }//end for //遍历整个棋盘 for(int i=1; i <= R; i ++) { for (int j=1; j <= C; j ++) { initGrid(); path[0].r = i; path[0].c = j; pl = 1; int number = 0; if (grid[i][j] == KNIGHT) { number ++; } if (i == king.r && j == king.c) { number ++; } grid[i][j] = 1; //广度遍历到所有骑士 for (int k=0; k < pl; k ++ ) { int r = path[k].r; int c = path[k].c; //左斜上 if (r > 1 && c > 2 ) { if (grid[r-1][c-2] == 0) { path[pl].r = r -1; path[pl].c = c -2; grid[r-1][c-2] = grid[r][c] + 1; pl ++; }//end if else if(grid[r-1][c-2] == KNIGHT||grid[r-1][c-2] == KING) { path[pl].r = r -1; path[pl].c = c -2; grid[r-1][c-2] = grid[r][c] + 1; number ++; pl ++; }//end else if (number == kl + 1) { break; } } //左上 if (r > 2 && c > 1) { if (grid[r-2][c-1] == 0) { path[pl].r = r -2; path[pl].c = c -1; grid[r-2][c-1] = grid[r][c] + 1; pl ++; }//end if else if(grid[r-2][c-1] == KNIGHT||grid[r-2][c-1] == KING) { path[pl].r = r -2; path[pl].c = c -1; grid[r-2][c-1] = grid[r][c] + 1; number ++; pl ++; }//end else if (number == kl + 1) { break; } } //右上 if (r > 2 && c + 1 <= C) { if (grid[r-2][c+1] == 0) { path[pl].r = r - 2; path[pl].c = c+ 1; grid[r-2][c+1] = grid[r][c] + 1; pl ++; }//end if else if(grid[r-2][c+1] == KNIGHT||grid[r-2][c+1] == KING) { path[pl].r = r - 2; path[pl].c = c+ 1; grid[r-2][c+1] = grid[r][c] + 1; number ++; pl ++; }//end else if (number == kl + 1) { break; } } //右斜上 if (r > 1 && c + 2 <= C) { if (grid[r-1][c+2] == 0) { path[pl].r = r - 1; path[pl].c = c+ 2; grid[r-1][c+2] = grid[r][c] + 1; pl ++; }//end if else if(grid[r-1][c+2] == KNIGHT||grid[r-1][c+2] == KING) { path[pl].r = r - 1; path[pl].c = c+ 2; grid[r-1][c+2] = grid[r][c] + 1; number ++; pl ++; }//end else if (number == kl + 1) { break; } } //右斜下 if (r + 1 <= R && c + 2 <= C) { if (grid[r+1][c+2] == 0) { path[pl].r = r +1; path[pl].c = c+ 2; grid[r+1][c+2] = grid[r][c] + 1; pl ++; }//end if else if(grid[r+1][c+2] == KNIGHT||grid[r+1][c+2] == KING) { path[pl].r = r +1; path[pl].c = c+ 2; grid[r+1][c+2] = grid[r][c] + 1; number ++; pl ++; }//end else if (number == kl + 1) { break; } } //右下 if (r + 2 <= R && c + 1 <= C) { if (grid[r+2][c+1] == 0) { path[pl].r = r +2; path[pl].c = c+ 1; grid[r+2][c+1] = grid[r][c] + 1; pl ++; }//end if else if(grid[r+2][c+1] == KNIGHT||grid[r+2][c+1] == KING) { path[pl].r = r +2; path[pl].c = c+ 1; grid[r+2][c+1] = grid[r][c] + 1; number ++; pl ++; }//end else if (number == kl + 1) { break; } } //左下 if (r + 2 <= R && c - 1 >0) { if (grid[r+2][c-1] == 0) { path[pl].r = r +2; path[pl].c = c- 1; grid[r+2][c-1] = grid[r][c] + 1; pl ++; }//end if else if(grid[r+2][c-1] == KNIGHT||grid[r+2][c-1] == KING) { path[pl].r = r +2; path[pl].c = c- 1; grid[r+2][c-1] = grid[r][c] + 1; number ++; pl ++; }//end else if (number == kl + 1) { break; } } //左斜下 if (r + 1 <= R && c - 2 >0) { if (grid[r+1][c-2] == 0) { path[pl].r = r +2; path[pl].c = c+ 1; grid[r+1][c-2] = grid[r][c] + 1; pl ++; }//end if else if(grid[r+1][c-2] == KNIGHT||grid[r+1][c-2] == KING) { path[pl].r = r +2; path[pl].c = c+ 1; grid[r+1][c-2] = grid[r][c] + 1; number ++; pl ++; }//end else if (number == kl + 1) { break; } } }//end for bool tempflag = false; int tempresult =0 ; //判断国王是否在骑士到集结地的路上 for (int m=0; m< kl; m++ ) { int tempking = grid[king.r][king.c]; if (tempking + kingtoknight[m] == grid[knight[m].r][knight[m].c]) { tempflag = true; } tempresult += grid[knight[m].r][knight[m].c] -1; }//end for if (tempflag || flag) { if (tempresult < result) { result = tempresult; } } else { int minload = LARGE; int minindex = -1; for (int i=0; i<kl; i ++) { if (minload > kingtoknight[i]) { minload = kingtoknight[i]; minindex = i; }//end if }//end for int tempresult2 = tempresult + minload - grid[knight[i].r][knight[i].c] + grid[king.r][king.c]; if (tempresult2 < result) { result = tempresult2; } int tempresult3 = tempresult + kntok; if (tempresult3 < result) { result = tempresult3; } int absr = abs( knight[i].r - i ); int absc = abs( knight[i].c - j ); int tempresult4 = max(absr,absc) + tempresult; if (tempresult4 < result) { result = tempresult4; } } }//end j }//end i fout << result << endl; return 0; }