【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 }