游戏_动态规划
问题描述
小明在玩一个电脑游戏,游戏在一个n×m的方格图上进行,小明控制的角色开始的时候站在第一行第一列,目标是前往第n行第m列。
方格图上有一些方格是始终安全的,有一些在一段时间是危险的,如果小明控制的角色到达一个方格的时候方格是危险的,则小明输掉了游戏,如果小明的角色到达了第n行第m列,则小明过关。第一行第一列和第n行第m列永远都是安全的。
每个单位时间,小明的角色必须向上下左右四个方向相邻的方格中的一个移动一格。
经过很多次尝试,小明掌握了方格图的安全和危险的规律:每一个方格出现危险的时间一定是连续的。并且,小明还掌握了每个方格在哪段时间是危险的。
现在,小明想知道,自己最快经过几个时间单位可以达到第n行第m列过关。
输入格式
输入的第一行包含三个整数n, m, t,用一个空格分隔,表示方格图的行数n、列数m,以及方格图中有危险的方格数量。
接下来t行,每行4个整数r, c, a, b,表示第r行第c列的方格在第a个时刻到第b个时刻之间是危险的,包括a和b。游戏开始时的时刻为0。输入数据保证r和c不同时为1,而且当r为n时c不为m。一个方格只有一段时间是危险的(或者说不会出现两行拥有相同的r和c)。
输出格式
输出一个整数,表示小明最快经过几个时间单位可以过关。输入数据保证小明一定可以过关。
样例输入
3 3 3
2 1 1 1
1 3 2 10
2 2 2 10
样例输出
6
1 #include <iostream> 2 3 using namespace std; 4 5 struct Posdata{ 6 int time; 7 int newtime; 8 int dmin; 9 int dmax; 10 Posdata(int Ptime = 0, int Pnewtime = 0, int Pdmim = 0, int Pdmax = 0){ 11 time = Ptime, newtime = Pnewtime, dmin = Pdmim, dmax = Pdmax; 12 } 13 }; 14 15 Posdata data[100 + 1][100 + 1];//[0][0] not used; 16 17 int m, n, t; 18 int r, c, a, b; 19 20 #define isDanger(a,b,t) (data[a][b].dmin <= t && data[a][b].dmax >= t) 21 22 int main() 23 { 24 int i, j; 25 int ntime; 26 cin >> n >> m >> t; 27 //init 28 for (i = 1; i < n + 1; ++i) 29 for (j = 1; j < m + 1; ++j) 30 data[i][j] = Posdata(-1, -1, -1, -1); 31 //input 32 for (i = 0; i < t; ++i){ 33 cin >> r >> c >> a >> b; 34 data[r][c] = Posdata(-1, -1, a, b); 35 } 36 data[1][1].time = 0; 37 //1000 is a max num 38 for (ntime = 0; ntime < 1000; ntime++){ 39 for (i = 1; i < n + 1; i++){ 40 for (j = 1; j < m + 1; j++){ 41 if (data[i][j].time == ntime){ 42 if (i != n&&!isDanger(i + 1, j, ntime + 1)) 43 data[i + 1][j].newtime = ntime + 1; 44 if (j != m&&!isDanger(i, j + 1, ntime + 1)) 45 data[i][j + 1].newtime = ntime + 1; 46 if (i != 1 && !isDanger(i - 1, j, ntime + 1)) 47 data[i - 1][j].newtime = ntime + 1; 48 if (j != 1 && !isDanger(i, j - 1, ntime + 1)) 49 data[i][j - 1].newtime = ntime + 1; 50 } 51 } 52 } 53 for (i = 1; i < n + 1; i++){ 54 for (j = 1; j < m + 1; j++){ 55 data[i][j].time = data[i][j].newtime; 56 } 57 } 58 if (data[n][m].time != -1) 59 break; 60 } 61 cout << ntime + 1 << endl; 62 63 return 0; 64 }