这里贴下不用枚举方格是否为雷的方法

a表示输入标号,初始值为-1代表未探知

b表示当前格子是否有雷,初始化为0,0表示未探知,1表示探知肯定有雷,2表示探知肯定无雷(我也不知道为什么不初始化为-1,作死。。。)

。。。二是个坑啊,不能用多余的想法解题。。。也就是3个条件不能互影响,不能用别的条件得出来的b的值,大概就是全写成通过a的值来判断

一二三都是通过数字和周边已经确定的雷数的关系来的,比如数字为5,周边肯定5个雷,3个无雷,也用了集合包含来判断

二三中队列跳出的条件就是一轮下来,所有的未解决的数量都没发生变化

那么接着弄也不会有变化了。

有按更新周围格子不断更新外围可能修改的进行优化,也有按剩余探索格子数的优先队列进行优化

#include <cstdio>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <cassert>
#include <string>
#include <ctime>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <stack>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define req(i,a,b) for(int i=a;i>=b;i--)
#define rp(i,a) for(int i=head[a];i+1;i=edge[i].next)
#define cl(a,b) memset(a,b,sizeof a);
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mod 1000000007
const int inf = ~0u >> 2;
const ll INF = (1LL << 62) - 1;
double eps = 1e-9;
const int N = 1e6 + 5;
const int M = 221; int ans = 0, cnt = 0;
int n, m;
char str[M];
int a[N],b[N]; void getsure() {
for (int i = 3; i <= n; i+=3) {
b[i] = (a[i-1] - a[i - 2]+(b[i-3]==2?0:1))==0?2:1;
}
}
void getless() {
for (int i = 1; i <= n; i++) {
if (a[i] == 1) {
if (b[i - 1] == 1) {
b[i] = b[i + 1] = 2;
}
if (b[i] == 1) {
b[i - 1] = b[i + 1] = 2;
}
if (b[i + 1] == 1) {
b[i - 1] = b[i] = 2;
}
if (b[i - 1] == b[i] && b[i] == 2) {
b[i + 1] = 1;
}
if (b[i - 1] == b[i + 1] && b[i - 1] == 2) {
b[i] = 1;
}
if (b[i] == b[i + 1] && b[i] == 2) {
b[i - 1] = 1;
}
}
else if (a[i] == 2) {
if (b[i - 1] == 2) {
b[i] = b[i + 1] = 1;
}
if (b[i] == 2) {
b[i - 1] = b[i + 1] = 1;
}
if (b[i + 1] == 2) {
b[i - 1] = b[i] = 1;
}
if (b[i - 1] == b[i] && b[i] == 1) {
b[i + 1] = 2;
}
if (b[i - 1] == b[i + 1] && b[i - 1] == 1) {
b[i] = 2;
}
if (b[i] == b[i + 1] && b[i] == 1) {
b[i - 1] = 2;
}
}
}
}
int main() {
int t;
cin >> t;
while (t--) {
memset(a, 0, sizeof a);
memset(b, 0, sizeof b);
cin >> n;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
b[0] = b[n + 1] = 2;
for (int i = 1; i <= n; i++) {
if (a[i] == 3)
b[i - 1] = b[i] = b[i + 1] = 1;
}
for (int i = 1; i <= n; i++) {
if (a[i] == 0)
b[i - 1] = b[i] = b[i + 1] = 2;
} getsure();
reverse(a + 1, a + n+1);
reverse(b + 1, b + n+1);
getsure();
reverse(a + 1, a + n+1);
reverse(b + 1, b + n+1); getless();
reverse(a + 1, a + n+1);
reverse(b + 1, b + n+1);
getless();
reverse(a + 1, a + n+1);
reverse(b + 1, b + n+1); int cnt1 = 0;
for(int i=1;i<=n;i++)
if (b[i] == 1) {
cnt1++;
}
printf("%d", cnt1);
for (int i = 1; i <= n; i++)
if (b[i] == 1)
printf(" %d", i);
printf("\n");
int cnt2 = 0;
for (int i = 1; i <= n; i++)
if (b[i] == 2)
cnt2++;
printf("%d", cnt2);
for (int i = 1; i <= n; i++) {
if (b[i] == 2)
printf(" %d", i);
}
printf("\n");
}
return 0;
}

#include <cstdio>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <cassert>
#include <string>
#include <ctime>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <stack>
#include <set>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define req(i,a,b) for(int i=a;i>=b;i--)
#define rp(i,a) for(int i=head[a];i+1;i=edge[i].next)
#define cl(a,b) memset(a,b,sizeof a);
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mod 1000000007
const int inf = ~0u >> 2;
const ll INF = (1LL << 62) - 1;
double eps = 1e-9;
const int N = 2e2 + 5;
const int M = 221; int ans = 0, cnt = 0;
int n, m;
char str[M];
int dx[] = {1,1,1,-1,-1,-1,0,0};
int dy[] = {0,1,-1,0,1,-1,1,-1};
int a[N][N],b[N][N];
void setval(int i, int j, int val); void getinit() {
for(int i=1;i<=n;i++)
for (int j = 1; j <= m; j++) {
if (a[i][j] == 0) {
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if (a[ni][nj] == -1)
setval(ni, nj, 2);
}
}
}
}
void setk(int i, int j) {
if (i <= 0 || j <= 0 || i > n || j > m)
return;
int k = a[i][j];
if (a[i][j] != -1) {
int asum = 0;
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if (a[ni][nj] == -1)
asum += 1;
}
if (asum == k) {
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
setval(ni, nj, 1);
}
}
}
}
bool isok(int i, int j) {
if (i <= 0 || j <= 0 || i > n || j > m)
return false;
return true;
}
void setval(int i, int j,int value) {
if (i <= 0 || j <= 0 || i > n || j > m)
return;
if (a[i][j]==-1) {
if (b[i][j] == 0) {
b[i][j] = value;
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
setk(ni, nj);
}
}
}
} struct Node {
int x, y, d;
int operator <(const Node& rhs)const {
return d > rhs.d;
}
};
priority_queue<Node> q;
int getsum(int i, int j,int c) {
if (i <= 0 || j <= 0 || i > n || j > m) {
//printf("-1!!\n");
return -1;
}
int sum = 0;
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if (b[ni][nj] == c&&a[ni][nj]==-1) {
sum++;
}
}
return sum;
}
bool isdealed(int i, int j) {
if (i <= 0 || j <= 0 || i > n || j > m) {
//printf("-2!!\n");
return -1;
}
if (a[i][j] == -1)
return true;
if (a[i][j] == 0)
return true;
if (getsum(i, j, 0) == 0)
return true;
return false;
}
set<pair<int, int>> getpairs(int i, int j) {
if (i <= 0 || j <= 0 || i > n || j > m) {
//printf("-3!!\n");
return set<pair<int, int>>{};
}
set<pair<int, int>> pairs;
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if (a[ni][nj]==-1)
pairs.insert(make_pair(ni, nj));
}
return pairs;
}
bool iscontain(set<pair<int, int>> pairs, set<pair<int, int>> xpairs) {
if (pairs.size() <= xpairs.size())
return false;
bool exist = true;
for (auto var : xpairs)
{
if (pairs.count(var)==0) {
exist = false;
}
}
return exist;
}
void dealcontain(set<pair<int, int>> pairs, set <pair<int, int>> xpairs) {
for (auto var : pairs)
{
if (xpairs.count(var) == 0)
setval(var.first, var.second, 1);
}
}
void getcontain() {
int qcnt = 0;
while (!q.empty())q.pop();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] != -1&&!isdealed(i,j)) {
q.push(Node{ i,j,getsum(i,j,0) });
qcnt++;
}
}
}
int outtime = q.size();
int curtime = 0;
while (!q.empty()) {
Node x = q.top(); q.pop();
int sum = getsum(x.x, x.y, 0);
set<pair<int, int>> xpairs = getpairs(x.x, x.y);
vector<Node> surx;
for (int i = x.x - 2; i <= x.x + 2; i++) {
for (int j = x.y - 2; j <= x.y + 2; j++) {
if (!isok(i, j)||i==x.x&&j==x.y)
continue;
if (a[i][j] != -1) {
set<pair<int, int>> pairs = getpairs(i, j);
if (iscontain(xpairs, pairs) && a[x.x][x.y] == a[i][j] + (xpairs.size() - pairs.size())) {
dealcontain(xpairs, pairs);
}
}
}
}
if (!isdealed(x.x,x.y)){
if (getsum(x.x, x.y, 0) == sum) {
q.push(Node{ x.x,x.y,qcnt++ });
}
else{
q.push(Node{ x.x,x.y,getsum(x.x,x.y,0) });
}
curtime++;
}
else
{
outtime = q.size();
curtime = 0;
}
if (curtime == outtime+1) {
break;
}
} }
int main() {
int t;
cin >> t;
while (t--) {
memset(a, 0, sizeof a);
memset(b, 0, sizeof b);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
}
}
getinit();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
setk(i, j);
getcontain();
int cnt1 = 0;
for(int i=1;i<=n;i++)
for (int j = 1; j <= m; j++) {
if (b[i][j] == 1&&a[i][j]==-1) {
cnt1++;
}
}
int cnt2 = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (b[i][j] == 2&&a[i][j]==-1)
cnt2++;
}
printf("%d %d", cnt1,cnt2);
printf("\n");
}
return 0;
}

#include <cstdio>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <cassert>
#include <string>
#include <ctime>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <stack>
#include <set>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define req(i,a,b) for(int i=a;i>=b;i--)
#define rp(i,a) for(int i=head[a];i+1;i=edge[i].next)
#define cl(a,b) memset(a,b,sizeof a);
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mod 1000000007
const int inf = ~0u >> 2;
const ll INF = (1LL << 62) - 1;
double eps = 1e-9;
const int N = 2e2 + 5;
const int M = 221; int ans = 0, cnt = 0;
int n, m;
char str[M];
int dx[] = {1,1,1,-1,-1,-1,0,0};
int dy[] = {0,1,-1,0,1,-1,1,-1};
int a[N][N],b[N][N];
void setval(int i, int j, int val); void getinit() {
for(int i=1;i<=n;i++)
for (int j = 1; j <= m; j++) {
if (a[i][j] == 0) {
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
//if (a[ni][nj] == -1)
setval(ni, nj, 2);
}
}
if (a[i][j] == 8) {
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
setval(ni, nj, 1);
}
}
}
}
void setk(int i, int j) {
if (i <= 0 || j <= 0 || i > n || j > m)
return;
int k = a[i][j];
if (a[i][j] != -1) {
int asum = 0;
int bsum0 = 0;
int bsum1 = 0;
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if (a[ni][nj] == -1)
asum += 1;
if (b[ni][nj] == 1)
bsum1 += 1;
if (b[ni][nj] == 0)
bsum0 += 1;
}
if (bsum1 == k) {
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if (b[ni][nj] == 0)
setval(ni, nj, 2);
}
}
if (bsum1+bsum0==k) {
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if (b[ni][nj] == 0)
setval(ni, nj, 1);
}
}
}
}
bool isok(int i, int j) {
if (i <= 0 || j <= 0 || i > n || j > m)
return false;
return true;
}
void setval(int i, int j,int value) {
if (i < 0 || j <= 0 || i > n || j > m)
return;
//if (a[i][j]==-1) {
if (b[i][j] == 0) {
b[i][j] = value;
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
setk(ni, nj);
}
}
//}
} struct Node {
int x, y, d;
int operator <(const Node& rhs)const {
return d > rhs.d;
}
};
priority_queue<Node> q;
int getsum(int i, int j,int c) {
if (i <= 0 || j <= 0 || i > n || j > m) {
//printf("-1!!\n");
return -1;
}
int sum = 0;
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if (b[ni][nj] == c/*&&a[ni][nj]==-1*/) {
sum++;
}
}
return sum;
}
bool isdealed(int i, int j) {
if (i <= 0 || j <= 0 || i > n || j > m) {
//printf("-2!!\n");
return -1;
}
if (a[i][j] == -1)
return true;
if (a[i][j] == 0)
return true;
if (getsum(i, j, 0) == 0)
return true;
return false;
}
set<pair<int, int>> getpairs(int i, int j) {
if (i <= 0 || j <= 0 || i > n || j > m) {
//printf("-3!!\n");
return set<pair<int, int>>{};
}
set<pair<int, int>> pairs;
for (int k = 0; k < 8; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
//if (a[ni][nj]==-1)
if(b[ni][nj]==0)
pairs.insert(make_pair(ni, nj));
}
return pairs;
}
bool iscontain(set<pair<int, int>> pairs, set<pair<int, int>> xpairs) {
if (pairs.size() <= xpairs.size())
return false;
bool exist = true;
for (auto var : xpairs)
{
if (pairs.count(var)==0) {
exist = false;
}
}
return exist;
}
void dealcontain(set<pair<int, int>> pairs, set <pair<int, int>> xpairs) {
for (auto var : pairs)
{
if (xpairs.count(var) == 0)
setval(var.first, var.second, 1);
}
}
void getcontain() {
int qcnt = 0;
while (!q.empty())q.pop();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] != -1&&!isdealed(i,j)) {
q.push(Node{ i,j,getsum(i,j,0) });
qcnt++;
}
}
}
int outtime = q.size();
int curtime = 0;
while (!q.empty()) {
Node x = q.top(); q.pop();
int sum = getsum(x.x, x.y, 0);
set<pair<int, int>> xpairs = getpairs(x.x, x.y);
vector<Node> surx;
for (int i = x.x - 2; i <= x.x + 2; i++) {
for (int j = x.y - 2; j <= x.y + 2; j++) {
if (!isok(i, j)||i==x.x&&j==x.y)
continue;
if (a[i][j] != -1) {
set<pair<int, int>> pairs = getpairs(i, j);
if (iscontain(xpairs, pairs) && a[x.x][x.y]-getsum(x.x,x.y,1) == a[i][j]-getsum(i,j,1) + (xpairs.size() - pairs.size())) {
dealcontain(xpairs, pairs);
}
}
}
}
if (!isdealed(x.x,x.y)){
if (getsum(x.x, x.y, 0) == sum) {
q.push(Node{ x.x,x.y,qcnt++ });
}
else{
q.push(Node{ x.x,x.y,getsum(x.x,x.y,0) });
}
curtime++;
}
else
{
outtime = q.size();
curtime = 0;
}
if (curtime == outtime+1) {
break;
}
} }
int main() {
int t;
cin >> t;
while (t--) {
memset(a, -1, sizeof a);
memset(b, 0, sizeof b);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
if (a[i][j] != -1)
//b[i][j] = 2;
setval(i, j, 2);
}
}
for (int i = 0; i <= n + 1; i++) {
//setval(i, 0, 2);
//setval(i, m + 1, 2);
b[i][0] = b[i][m + 1] = 2;
}
for (int i = 0; i <= m + 1; i++) {
//setval(0, i, 2);
//setval(n + 1, i, 2);
b[0][i] = b[n + 1][i] = 2;
}
getinit();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
setk(i, j);
getcontain();
int cnt1 = 0;
for(int i=1;i<=n;i++)
for (int j = 1; j <= m; j++) {
if (b[i][j] == 1&&a[i][j]==-1) {
cnt1++;
}
}
int cnt2 = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (b[i][j] == 2&&a[i][j]==-1)
cnt2++;
}
printf("%d %d", cnt1,cnt2);
printf("\n");
}
return 0;
}

Hihocoder 小Hi小Ho扫雷作死一二三的更多相关文章

  1. hihoCoder 1114 小Hi小Ho的惊天大作战:扫雷·一 最详细的解题报告

    题目来源:小Hi小Ho的惊天大作战:扫雷·一 解题思路:因为只要确定了第一个是否有地雷就可以推算出后面是否有地雷(要么为0,要么为1,如果不是这两个值就说明这个方案行不通),如果两种可能中有一种成功, ...

  2. hiho #1114 : 小Hi小Ho的惊天大作战:扫雷·一

    #1114 : 小Hi小Ho的惊天大作战:扫雷·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 故事背景:密室.监视器与充满危机的广场 “我们还是循序渐进,先来考虑这 ...

  3. 【转】HTML5的小知识点小集合

    html5的小知识点小集合 html5知识   1.  Doctype作用?标准模式与兼容模式各有什么区别? (1).<!DOCTYPE>声明位于位于HTML文档中的第一行,处于<h ...

  4. html5的小知识点小集合

      html5的小知识点小集合 html5知识   1.  Doctype作用?标准模式与兼容模式各有什么区别? (1).<!DOCTYPE>声明位于位于HTML文档中的第一行,处于< ...

  5. 微信小程序即将开放申请?微信小论坛小程序专场16日或可见分晓

    9月22号微信小程序内测至今已经好一段时间了,首批只开放了200个名额,没拿到内测资格的朋友早就等到心急了.就在刚刚,微信公开课宣布微信小论坛小程序专场即将在11月16号举行,微信公众平台小程序会在当 ...

  6. 如何获取微信小店小程序的AppID

    2017年11月16日,微信有一个重磅的宣布:为了帮商家在微信内快速开店,方便商家和用户之间沟通,所有认证公众号,可快速创建微信小店小程序.这个改变是否能给微信小店带来新的生机?还需要时间的考验.微信 ...

  7. 微信小游戏 小程序与小游戏获取用户信息接口调整 wx.createUserInfoButton

    参考: 小程序•小故事(6)——微信登录能力优化 小程序•小故事(4)——获取用户信息 本篇主要是讲微信getUserInfo接口不再出现授权弹框 那么原来getUserInfo是怎么样?修改之后又是 ...

  8. 微信小程序再次升级:卖货小店小程序不用开发也能进行交易

    卖货小店小程序,不用开发一行代码也能帮商家实现交易功能,这个真是几家欢喜几家愁啊,对于开发小程序商城的公司来说,这个无疑是一个雷霆之际,第一反应就是,这下完了,小程序自身就支持交易,那还要我们这些第三 ...

  9. python小技巧 小知识

    python小技巧 小知识 python系统变量(修改调用shell命令路径)或用户空间说明 20150418 python调用系统命令,报找不到.怎么办? 类似执行shell的: [ -f /etc ...

随机推荐

  1. 【USACO02FEB】Rebuilding Roads 重建道路 题解(树形DP)

    题目链接 题目大意:问使含有$p$个节点的子树分离至少需要去掉几条边. ------------------ 设$f[i][j]$表示以$i$为根的子树保留$j$个节点所去掉的最少边数. 初始化$f[ ...

  2. 基于开源串口调试助手修改的qcom

    代码已上传码云: https://gitee.com/fensnote/qcom.git 源代码用于串口编程的学习很有价值,谢谢Qter的开源项目,感谢花心萝卜工作室的修改版本. 开源的qt开发的串口 ...

  3. c++日志工具spdLog

    c++日志工具spdLog简单使用示例代码 spdlog直接引用头文件就可以使用,这一点还是比较方便的,也是刚入门使用,下面是在源码的示例代码基础上修改测试的代码: #include <cstd ...

  4. 如果连这10个Python缩写都不知道,那你一定是Python新手

    简介 对于许多开始学习编程的人来说,Python已经成为他们的首选.Python有非常直观的语法和支持动态类型的灵活性.此外,它是一种解释语言,这使得使用交互式控制台进行学习成为可能.基本上,我们只需 ...

  5. jQuery 购物车案例

    h1 { text-align: center; } .cart { width: 1200px; height: 600px; margin: 0 auto; border: 1px solid # ...

  6. JVM与Java体系结构

    参考笔记:https://blog.csdn.net/weixin_45759791/article/details/107322503 前言 作为Java工程师的你曾被伤害过吗?你是否也遇到过这些问 ...

  7. 【LeetCode/LintCode】 题解丨字节跳动试题:第k大的子数组

    给定一个长度为n的数组a,它有n(n+1)/2​​个子数组.请计算这些子数组的和,然后按照升序排列,并返回排序后第k个数. 1≤n≤10​^5 1≤a​i≤10^​9 1≤k≤​n(n+1)/2 在线 ...

  8. java 打印流与commons-IO

    一 打印流 1.打印流的概述 打印流添加输出数据的功能,使它们能够方便地打印各种数据值表示形式. 打印流根据流的分类: 字节打印流 PrintStream 字符打印流 PrintWriter 方法: ...

  9. Android学习进程 Java引用 Rxjava MVP

    第一份Android开发工作,以便于记录学习进程 Java引用 Java没有显式的使用指针,但对象的访问仍是通过指针实现的,所以直接对象之间的赋值会导致存储空间是数据的改变,如设置两个对象,其中对象一 ...

  10. 学长小清新题表之UOJ 14.DZY Loves Graph

    学长小清新题表之UOJ 14.DZY Loves Graph 题目描述 \(DZY\)开始有 \(n\) 个点,现在他对这 \(n\) 个点进行了 \(m\) 次操作,对于第 \(i\) 个操作(从 ...