Thanks a lot for helping Harry Potter in finding the Sorcerer's Stone of Immortality in October. Did we not tell you that it was just an online game ? uhhh! now here is the real onsite task for Harry. You are given a magrid S ( a magic grid ) having R rows and C columns. Each cell in this magrid has either a Hungarian horntail dragon that our intrepid hero has to defeat, or a flask of magic potion that his teacher Snape has left for him. A dragon at a cell (i,j) takes away |S[i][j]| strength points from him, and a potion at a cell (i,j) increases Harry's strength by S[i][j]. If his strength drops to 0 or less at any point during his journey, Harry dies, and no magical stone can revive him.
Harry starts from the top-left corner cell (1,1) and the Sorcerer's Stone is in the bottom-right corner cell (R,C). From a cell (i,j), Harry can only move either one cell down or right i.e., to cell (i+1,j) or cell (i,j+1) and he can not move outside the magrid. Harry has used magic before starting his journey to determine which cell contains what, but lacks the basic simple mathematical skill to determine what minimum strength he needs to start with to collect the Sorcerer's Stone. Please help him once again.
Input (STDIN):
The first line contains the number of test cases T. T cases follow. Each test case consists of R C in the first line followed by the description of the grid in R lines, each containing C integers. Rows are numbered 1 to R from top to bottom and columns are numbered 1 to C from left to right. Cells with S[i][j] < 0 contain dragons, others contain magic potions.
Output (STDOUT):
Output T lines, one for each case containing the minimum strength Harry should start with from the cell (1,1) to have a positive strength through out his journey to the cell (R,C).
Constraints:
1 ≤ T ≤ 5
2 ≤ R, C ≤ 500
-10^3 ≤ S[i][j] ≤ 10^3
S[1][1] = S[R][C] = 0
Sample Input:
3
2 3
0 1 -3
1 -2 0
2 2
0 1
2 0
3 4
0 -2 -3 1
-1 4 0 -2
1 -2 -3 0
Sample Output:
2
1
2
要用dp来做,dfs会超时。同时不能从起点计算,要从终点往回推。因为如果用正向来做的话,不仅仅要保留该点的当前分数值,还要保留起点到该点所需的分数值,这样就控制不了了,但是逆向思维,从终点往回退,只需要保留该点到终点所需要的分值,而不需要考虑该点还剩多少分值。
#include<iostream> #include<stdio.h> #include<string.h> #include<cmath> #include<math.h> #include<algorithm> #include<set> typedef long long ll; using namespace std; #define INF 1e9+7 int a[510][510]; int dp[510][510];//dp[i][j]表示从该点到终点所需要的最少分数 int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) scanf("%d",&a[i][j]); } dp[n-1][m-1]=1;//每个点最小是1,初始化终点是1 for(int i=n-1;i>=0;i--)//逆向思维。。 { for(int j=m-1;j>=0;j--) { if(i!=n-1&&j==m-1) { dp[i][j]=max(1,dp[i+1][j]-a[i][j]); } else if(i==n-1&&j!=m-1) { dp[i][j]=max(1,dp[i][j+1]-a[i][j]); } else if(i!=n-1&&j!=m-1) { dp[i][j]=max(1,min(dp[i+1][j]-a[i][j],dp[i][j+1]-a[i][j])); } } } printf("%d ",dp[0][0]); } return 0; }
The wizards and witches of Hogwarts School of Witchcraft found Prof. Binn's History of Magic lesson to be no less boring than you found your own history classes. Recently Binns has been droning on about Goblin wars, and which goblin civilization fought which group of centaurs where etc etc. The students of Hogwarts decided to use the new-fangled computer to figure out the outcome of all these wars instead of memorizing the results for their upcoming exams. Can you help them?
The magical world looks like a 2-D R*C grid. Initially there are many civilizations, each civilization occupying exactly one cell. A civilization is denoted by a lowercase letter in the grid. There are also certain cells that are uninhabitable (swamps, mountains, sinkholes etc.) - these cells are denoted by a '#' in the grid. All the other cells - to which the civilizations can move - are represented by a '.' in the grid.
A cell is said to be adjacent to another cell if they share the same edge - in other words, for a cell (x,y), cells (x-1, y), (x, y-1), (x+1, y), (x, y+1) are adjacent, provided they are within the boundaries of the grid. Every year each civilization will expand to all unoccupied adjacent cells. If it is already inhabited by some other civilization, it just leaves the cell alone. It is possible that two or more civilizations may move into an unoccupied cell at the same time - this will lead to a battle between the civilizations and the cell will be marked with a '*'. Note that the civilizations fighting in a particular cell do not try to expand from that cell, but will continue to expand from other cells, if possible.
Given the initial grid, output the final state of the grid after no further expansion by any civilization is possible.
Input (STDIN):
The first line contains T, the number of cases. This is followed by T test case blocks.
Each test case contains two integers, R, C.
This is followed by R lines containing a string of length C. The j-th letter in the i-th row describes the state of the cell in year 0.
Each cell is either a
1. '.' which represents an unoccupied cell
2. '#' which represents a cell that cannot be occupied
3. A civilization represented by a lowercase letter ('a' - 'z')
Output (STDOUT):
For each test case, print the final grid after no expansion is possible. Apart from the notations used in the input, use '*' to denote that a battle is being waged in that particular cell.
Print a blank line at the end of each case.
Constraints:
1 <= R, C <= 500
1 <= T <= 5
Sample Input:
5
3 5
#####
a...b
#####
3 4
####
a..b
####
3 3
#c#
a.b
#d#
3 3
#c#
...
a.b
3 5
.....
.#.#.
a...b
Sample Output:
#####
aa*bb
#####
####
aabb
####
#c#
a*b
#d#
#c#
acb
a*b
aa*bb
a#.#b
aa*bb
一道bfs的题。。
#include<stdio.h> #include<string.h> #include<queue> using namespace std; int T; char map[505][505];//表示[i][j]该点 int flag[505][505];//表示所有国家到[i][j]的时间里面的最小时间 int direction[4][2]={0,1,0,-1,1,0,-1,0};//4个方向 int R,C; struct Node { int x,y,num;//x,y表示坐标,num表示第几个时间点到达。 char s;//s表示字母 }; void BFS() { memset(flag,0,sizeof(flag)); queue<Node>q; for (int i=0;i<R;i++) for (int j=0;j<C;j++) { if(map[i][j]>='a'&&map[i][j]<='z')//一开始把所有国家存储进去 q.push((Node){i,j,0,map[i][j]});//i,j,0,map[i][j]分别对应Node中的4个坐标。 } while (!q.empty()) { Node t=q.front(); q.pop(); if(map[t.x][t.y]=='*') continue;//如果这个地方已经发生战争就可以直接退出 for(int i=0;i<4;i++) { int xx=t.x+direction[i][0]; int yy=t.y+direction[i][1]; if(xx<0||xx>=R||yy<0||yy>=C||map[xx][yy]=='*'||map[xx][yy]=='#')//超出范围或者不能走或者在发生战争 { continue; } if(map[xx][yy]=='.')//可以走,则改变那个点 ,入队 { map[xx][yy]=t.s; q.push((Node){xx,yy,t.num+1,map[xx][yy]}); flag[xx][yy]=t.num+1; } if(map[xx][yy]!=t.s&&flag[xx][yy]==t.num+1)//满足突破口,不同的国家在同一个时间段同一个地方相遇,则要发生战争 map[xx][yy]='*'; } } } int main() { while (scanf("%d",&T)!=EOF) { while (T--) { scanf("%d%d",&R,&C); for (int i=0;i<R;i++) scanf("%s",map[i]); BFS(); for (int i=0;i<R;i++) printf("%s ",map[i]); } } return 0; }