SJTU SCPC Monthly Oct.2013 Problem D. bee
我艹,这尼玛这里写了个v.y=v.x+dy[i];找了你妹这么久!
【题目描述】
还记得童年时的红白机射击游戏《小蜜蜂》吗,爱丽丝可是这款游戏的高手!
现在的爱丽丝正在重温儿时的回忆,她正在玩小蜜蜂游戏的一个简化版本。 游戏的地图由一个m*n的方格构成,标号从(0, 0)到(m - 1, n - 1),开始的时候爱丽丝的飞机正在左下角的方格(0, 0)中,地图上一共有c个小蜜蜂零散地各自分布在地图上c个不同的格子里,没有一个各自有两个小蜜蜂。
每个单位时间,所有的小蜜蜂将会移动到各自所在的格子所在的下方的格子(即从(x, y)移向(x - 1, y)),若小蜜蜂已在地图的底端,则将移动出游戏地图,不会再对游戏产生任何影响。
每个时刻爱丽丝的飞机可以选择:
1.向上发射一发子弹,子弹会击中爱丽丝的飞机所在列向上的最近的一只没有被击中过的小蜜蜂,如果这一列没有小蜜蜂则这发子弹不会击中任何小蜜蜂。爱丽丝有无限发子弹。 2.向上下左右相邻的格子移动,爱丽丝的飞机不允许移出地图。
任意时刻开始的时候,如果爱丽丝和某一个未被击中的小蜜蜂在同一个格子上,或者爱丽丝的飞机尝试向一个当前已经有未被击中的小蜜蜂的格子移动,爱丽丝的飞机将会爆炸,游戏结束。
游戏的目的将飞机移向地图最上方的一行,及如果爱丽丝的飞机成功移动到了(m - 1, y),则爱丽丝获胜,爱丽丝想知道最短的时间来获取这盘游戏的胜利,她最短需要多少单位的时间?
【输入格式】
输入入的第一行包含一个整数T,表示数据的组数。 接下来每组数据的第一行包括三个整数,依次为m、n和c,意义如题目描述中所述。 接下来的c行每行包括两个整数x和y,代表每个小蜜蜂的初始位置。
【输出格式】
输出T行,每行包括一个整数,表示爱丽丝最短可以获胜的时间。
【样例输入】
2
4 2 2
3 0
2 0
4 2 3
3 0
2 0
1 1
【样例输出】
4
5
【数据范围】
1<=m,n<=50
0<=x<m,0<=y<n< p="">
1<=c<=8
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <map> 3 #include <queue> 4 #include <vector> 5 #include <string> 6 #include <cstdio> 7 #include <cstring> 8 #include <iostream> 9 #include <algorithm> 10 using namespace std; 11 #define maxn 105 12 #define mod 1000000007 13 #define ll long long 14 #define INF 0x7fffffff 15 int n, m, c; 16 struct point{ int x, y, s; }; 17 point p[11]; 18 int vis[55][55][257]; 19 int dp[55][55][257]; 20 int dx[]={ 1, -1, 0, 0 }; 21 int dy[]={ 0, 0, 1, -1 }; 22 int ok(int s,int t,int x,int y){ 23 if (x <0 || x >= n||y < 0 || y >= m)return 0; 24 for (int i = 0; i < c; i++) 25 if ((s&(1 << i))&& y == p[i].y && (p[i].x - t == x || p[i].x - t - 1 == x))return 0; 26 return 1; 27 } 28 int bfs(){ 29 queue<point>q; 30 point u,v; 31 u.x = 0, u.y = 0, u.s = (1 << c) - 1; 32 vis[u.x][u.y][u.s] = 1; 33 dp[u.x][u.y][u.s] = 0; 34 q.push(u); 35 while (!q.empty()){ 36 u = q.front(); q.pop(); 37 if (u.s > 0){ 38 int t = -1; 39 for (int i = 0; i < c; i++){ 40 if ((u.s&(1 << i)) && u.y == p[i].y&&u.x + dp[u.x][u.y][u.s] < p[i].x){ 41 if (t == -1)t = i; 42 else if (p[i].x<p[t].x)t = i; 43 } 44 } 45 if (t >= 0){ 46 int ts = u.s ^ (1 << t); 47 if (dp[u.x][u.y][ts]>dp[u.x][u.y][u.s] + 1){ 48 dp[u.x][u.y][ts] = dp[u.x][u.y][u.s] + 1; 49 if (!vis[u.x][u.y][ts]){ 50 vis[u.x][u.y][ts] = 1; 51 v.x = u.x, v.y = u.y, v.s = ts; 52 q.push(v); 53 } 54 } 55 } 56 } 57 for (int i = 0; i < 4; i++){ 58 v.x = u.x + dx[i]; 59 v.y = u.y + dy[i]; 60 v.s = u.s; 61 if (ok(v.s,dp[u.x][u.y][u.s],v.x,v.y) && dp[v.x][v.y][v.s]>dp[u.x][u.y][u.s] + 1){ 62 dp[v.x][v.y][v.s] = dp[u.x][u.y][u.s] + 1; 63 if (!vis[v.x][v.y][v.s]){ 64 vis[v.x][v.y][v.s] = 1; 65 q.push(v); 66 } 67 } 68 } 69 vis[u.x][u.y][u.s] = 0; 70 } 71 int ans = INF; 72 for (int i = 0; i < m; i++)for(int j=0;j<256;j++)ans = min(ans, dp[n - 1][i][j]); 73 return ans; 74 } 75 int main(){ 76 int cas = 1; 77 int t; 78 scanf("%d", &t); 79 while (t--){ 80 scanf("%d%d%d", &n, &m, &c); 81 memset(vis, 0, sizeof vis); 82 memset(dp, 31, sizeof dp); 83 for (int i = 0; i < c; i++)scanf("%d%d", &p[i].x, &p[i].y); 84 printf("%d\n", bfs()); 85 } 86 return 0; 87 }
浙公网安备 33010602011771号