11B:夺宝探险
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
你无意中发现了装满了宝藏的迷宫,你想要获得尽可能多的宝藏,但是迷宫里的机关阻碍了你的计划。迷宫的地面是M行N列的矩形网格,每格是一块带有机关且放置了1个宝藏的地砖,宝藏一共有K种,用1-K表示其种类,迷宫的入口只有一个,为迷宫的第一行第一列。地砖的机关如下:
1. 每次你只能踏到你与你所在地砖相邻的地砖上(即前后左右4块);
2. 当你踏上某块地砖后,其上的宝藏(假设种类为k)自动归属你,同时所有放置了种类为k的宝藏的地砖碎裂,你无法踏上,你当前所在的地砖在你离开后也会立刻碎裂;
3. 当你无路可走的时候,你会被传送回迷宫出口,无法再进入迷宫。
你想知道你最多能获得多少宝藏。
- 输入
- 输入的第一行是三个用空格隔开的整数,分别是M、N和K(1 <= M,N <= 20, 1 <= K <= 100)
之后是M行,每行包含N个范围为1-K的整数,用空格隔开,表示放置的宝藏种类 - 输出
- 只有一行,为一个整数,表示最多能获得的宝藏个数。
- 样例输入
-
3 4 5 1 2 3 3 2 1 4 3 1 5 1 2
- 样例输出
-
4
1 #include<iostream> 2 using namespace std; 3 int m, n, k; 4 int a[22][22]; 5 bool jewel[101]; 6 int have = 0; //获得的宝石数 7 int ans = 0; 8 int dirx[4] = {0,0,1,-1}; 9 int diry[4] = {1,-1,0,0}; 10 void dfs(int x, int y){ 11 for(int i = 0; i < 4; i++){ 12 int nx = x+dirx[i]; 13 int ny = y+diry[i]; 14 if(!jewel[a[nx][ny]]){ 15 jewel[a[nx][ny]] = true; 16 have++; 17 dfs(nx, ny); 18 have--; 19 jewel[a[nx][ny]] = false; 20 } 21 } 22 ans = max(ans, have); 23 } 24 int main(){ 25 cin>>m>>n>>k; 26 int i, j; 27 for(i = 1; i <= m; i++) 28 for(j = 1; j <= n; j++) 29 cin>>a[i][j]; 30 jewel[a[1][1]] = true; 31 jewel[0] = true; 32 have = 1; 33 dfs(1,1); 34 cout<<ans; 35 return 0; 36 }
备注:耶,一道dfs水题一次就过非常快乐。
依然,地图从1开始存比较便利。
两个不一样的地方,一个是因为“连锁塌陷”效应,不用设置二维visited数组,只需要设置一个jewel来记录有没有获得这种宝石就可以了。
第二个就是dfs没有啥边界条件,迷宫没有终点,无路可走了就是终点。
注意若a[i][j]==0,代表着这个格非法不能走,只要巧妙的把jewel[0]设置为1就可以了,防止它走,这样就不用再特意判断新的格子有没有越界。