扫雷啊,暴力搜索,给定五个位置,分析一下,最多只有16个周围的的格子,然后一一枚举就好了,2^16种,压力很小
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#define col 30
using namespace std;
int dx[8]= {-1,-1,-1,0,0,1,1,1};
int dy[8]= {-1,0,1,-1,1,-1,0,1};
int map[16*30],s[20],vis[16*30],co[6],a,t;
int judge(int x,int y) //判断x,y这个位置周围布雷情况是否符合
{
int total=0;
for(int i=0;i<8;i++)
{
int nx=x+dx[i],ny=y+dy[i],p=nx*col+ny,flag=1;
for(int j=0;j<a;j++) if(p==co[j]) {flag=0;break;}
if(!flag) continue;
if(nx>=0&&nx<16&&ny>=0&&ny<30)
total+=map[p];
}
if(total==map[x*col+y]) return 1;
return 0;
}
int search()
{
int N=(int)pow(2,t),flag=1,k=0,now[20]={0},ans=0,first=1;
//cout<<N<<endl;
for(int i=0;i<N;i++) //利用二进制数枚举每种情况,分布在MAP数组中
{
int fg=1,d=i;
for(int j=0;j<t;j++)
{
map[s[j]]=d&1;
d/=2;
}
for(int j=0;j<a;j++) if(!judge(co[j]/col,co[j]%col)) {fg=0;break;}
if(!fg) continue; //如果给定的几个位置有一个不满足情况,继续循环
flag=0;d=i;k=0;
for(int j=0;j<t;j++) //用vis记录布雷情况始终不变的位置
{
if(first)
{
vis[s[j]]=map[s[j]];
first=0;
//if(vis[s[j]]==1) ans++;
}
/*else if(map[s[j]]==vis[s[j]])
{
now[k++]=s[j];ans++;
}*/
else if((map[s[j]]==1&&vis[s[j]]==0)||(map[s[j]]==0&&vis[s[j]]==1))
{
vis[s[j]]=0;
}
}
//return ans;
}
if(flag) return 0;
for(int i=0;i<t;i++) if(vis[s[i]]==1) ans++;
return ans;
}
int main()
{
//freopen("data.txt","r",stdin);
int T;
cin>>T;
while(T--)
{
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
int x,y,num;
cin>>a;
t=0;
for(int i=0; i<a; i++)
{
cin>>x>>y>>num;
x-=1;y-=1;
vis[x*col+y]=1;
map[x*col+y]=num;
co[i]=x*col+y;
}
for(int i=0;i<a;i++)
{
x=co[i]/col;
y=co[i]%col;
for(int j=0; j<8; j++)
{
int nx=x+dx[j],ny=y+dy[j],p=nx*col+ny;
if(nx>=0&&nx<16&&ny>=0&&ny<30&&!vis[p]) {s[t++]=p;vis[p]=1;}
}
}
//cout<<t<<endl;
printf("%d\n",search());
}
return 0;
}