【lightoj-1046】Rider(BFS)
链接:http://www.lightoj.com/volume_showproblem.php?problem=1046
题意:
给m*n的棋盘,数字k代表这个位置上有棋子,并且一步可以连续跳1-k下,求所有棋子跳到同一位置的最小步数。
思路
容易想到用bfs,计算所有棋子在一个格子的步数,找出步数最小的格子就可以了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 char mp[12][12]; 4 int num[12][12], n, m; 5 bool vis[102][12][12]; 6 struct node 7 { 8 int x, y, step, jumpnum; 9 }; 10 node s; 11 void bfs(int cnt, int tiao) 12 { 13 int nx[8][2] = {{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}}; 14 queue<node>Q; 15 Q.push(s); 16 while(!Q.empty()) 17 { 18 s = Q.front(); 19 Q.pop(); 20 for(int k = 0; k < 8; k++) 21 { 22 node t = s; //这句一定要放在循环里!!之前放在外边一直WA.. 23 t.x = s.x + nx[k][0]; 24 t.y = s.y + nx[k][1]; 25 if(t.x<0||t.x>=m||t.y<0||t.y>=n||vis[cnt][t.x][t.y]) continue; 26 if(t.jumpnum == 1) 27 { 28 t.jumpnum = tiao; 29 vis[cnt][t.x][t.y] = 1; 30 if(tiao == 1) //若k=1那么也要步数+1 31 t.step = s.step+1; 32 Q.push(t); 33 } 34 else if(t.jumpnum == tiao) 35 { 36 t.step = s.step+1; 37 t.jumpnum = s.jumpnum -1; 38 vis[cnt][t.x][t.y] = 1; 39 Q.push(t); 40 } 41 else //t.jumpnum减到1之前都不增加步数 42 { 43 t.jumpnum = s.jumpnum -1; 44 vis[cnt][t.x][t.y] = 1; 45 Q.push(t); 46 } 47 num[t.x][t.y] += t.step; 48 } 49 } 50 } 51 int main() 52 { 53 int t, cas = 0; 54 cin>>t; 55 //freopen("1.txt", "w", stdout); 56 while(t--) 57 { 58 int cnt =0 ; 59 memset(num, 0, sizeof num); 60 memset(vis, 0, sizeof vis); 61 scanf("%d%d", &m, &n); 62 for(int i = 0; i < m; i++) 63 scanf("%s", mp[i]); 64 for(int i = 0; i < m; i++) 65 for(int j = 0; j < n; j++) 66 { 67 if(mp[i][j] != '.') 68 { 69 vis[++cnt][i][j] = 1; 70 s.x = i, s.y = j, s.jumpnum = mp[i][j]-'0', s.step = 0; 71 bfs(cnt, mp[i][j]-'0'); 72 } 73 } 74 int ans = 1e9, ii, jj, k; 75 for(int i = 0; i < m; i++) 76 for(int j = 0; j < n; j++) 77 { 78 for(k = 1 ; k <= cnt; k++) 79 if(!vis[k][i][j]) break; 80 if(k==cnt+1&&ans > num[i][j]) 81 ans = num[i][j], ii = i, jj = j; 82 } 83 printf("Case %d: %d\n", ++cas, ans==1e9?-1:ans); 84 } 85 }