您的位置:首页 > 其它

UVALive 6849 Landmine Cleaner(贪心、扫雷经典游戏)

2015-12-12 17:57 387 查看
题意:

给定N,M≤1000的数字雷图,试恢复原来的雷图,输入保证答案唯一

有雷的格子显示3+9宫格雷数,无雷的格子显示0+9宫格雷数

分析:

123
456
789
我们以3∗3的数字雷图为例,如上图

记ai:=显示数,ansi:=有雷与否

观察1号格子,它掌控4个格子,若无雷显示[0,3],有雷则显示[4,8],显然我们可以得到ans1=a1>3

确定有雷之后我们把多余的3减去,也就是 if(ansi) ai−=3

接下来我们观察4号格子,我们可以发现一个等式a4−a1=ans7+ans8<=2(多余的3已经减去了)

那么显然如果a4−a1>2的话这个格子一定有雷了

接下来我们观察2,5两个格子,我们在a2的基础上减掉前一列也就是ans1和ans4的影响

我们发现,此时问题跟刚才一样了,同样的4个格子,ans2=a2>3

对于5号格子显然可以得到ans5=a1−ans1−ans2−ans4

接下来我们只要重复这个过程就可以得到所有格子的答案了

注意最后一行的时候,消除前一列的影响的时候,仅仅只有一个格子

除了消去前一列的影响,每次计算还要消去前一行的影响

这种题debug还是自己写数据生成器吧

代码:

//
//  Created by TaoSama on 2015-12-12
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e3 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

int n, m, a

;
bool ans

;

void setMine(int i, int j) {
ans[i][j] = true;
a[i][j] -= 3;
}

void delLastColumn(int i, int j) {
a[i][j] -= ans[i][j - 1];
if(i < n) a[i][j] -= ans[i + 1][j - 1];
}

void see(int i, int j) {
printf("a[%d][%d] = %d ans: %d\n", i, j, a[i][j], ans[i][j]);
}

int main() {
#ifdef LOCAL
freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);

int t; scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
memset(a, 0, sizeof a);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
scanf("%d", &a[i][j]);

memset(ans, false, sizeof ans);
for(int i = 1; i <= n; i += 2) {
for(int j = 1; j <= m; ++j) //delete last line
a[i][j] -= ans[i - 1][j - 1] + ans[i - 1][j] + ans[i - 1][j + 1];

//is mine
if(a[i][1] > 3) setMine(i, 1);
//only 2 left
if(a[i + 1][1] - a[i][1] > 2) setMine(i + 1, 1);

for(int j = 2; j <= m; ++j) {
//              see(i, j);
delLastColumn(i, j);
//              see(i, j);
if(a[i][j] > 3) setMine(i, j);
ans[i + 1][j] = a[i][j - 1] - ans[i][j - 1] - ans[i + 1][j - 1] - ans[i][j];
}
}

for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j)
putchar("-L"[ans[i][j]]);
puts("");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  贪心 扫雷