还没时间写思路思想…先挂着
#include<bits/stdc++.h>
using namespace std;
int board[20][20] = {0};
int ans;
int n,m,M;
int dx[] = {1,0,-1,0,-1,-1,1,1};
int dy[] = {0,-1,0,1,1,-1,1,-1};
bool in(int x,int y)
{
return 1<=x&&x<=n&&1<=y&&y<=m;
}
bool legal(int x,int y)///一个点是否合法
{
if(board[x][y]==-1) return true;
if(board[x][y]==1){
for(int i=0;i<8;i++){
int tx = x + dx[i],ty = y + dy[i];
if(in(tx,ty)){
if(!board[tx][ty]) return true;
}
}
return false;
}
else{
int cnt = 0;
for(int i=0;i<8;i++){
int tx = x + dx[i],ty = y + dy[i];
if(in(tx,ty)&&board[tx][ty]) cnt++;
}
if(cnt>M) return false;
return true;
}
}
void dfs(int x,int y,int now,int last)
{
if(now+last<=ans) return;
if(x>n){
if(legal(n,m)&&legal(n,m-1)){
ans = max(ans,now);
}
return;
}
for(int i=0;i<2;i++){
board[x][y] = i;
if(y==m){
if(legal(x-1,y-1)&&legal(x-1,y)){
dfs(x+1,1,now+i,last-1);
}
}
else if(x==n){
if(legal(x,y-1)&&legal(x-1,y-1)){
dfs(x,y+1,now+i,last-1);
}
}
else{
if(legal(x-1,y-1)){
dfs(x,y+1,now+i,last-1);
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
memset(board,-1,sizeof(board));
ans = 0;
scanf("%d%d%d",&n,&m,&M);
dfs(1,1,0,m*n);
printf("%d\n",ans);
}
return 0;
}
他人代码分析:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
using namespace std;
const int inf = 0x3f3f3f3f;
const long long int INF = 1e18;
typedef long long LL;
int T;
int n, m, K, ans;
int mmp[10][10];
int x[] = { 1,1,1,0,0,-1,-1,-1 };
int y[] = { 1,0,-1,1,-1,1,0,-1 };
bool check(int nn, int mm) ///判断此点的合法性
{
if (mmp[nn][mm] == inf)return true;
if (mmp[nn][mm]) ///此地是雷
{
for (int i = 0; i < 8; i++)
{
int xx = nn + x[i], yy = mm + y[i];
if (xx >= 1 && xx <= n&&yy >= 1 && yy <= m)
{
if (!mmp[xx][yy])return true;///雷的四周有一个空位就满足条件
}
}
return false;
}
else///此地是空地
{
int cnt = 0;
for (int i = 0; i < 8; i++)
{
int xx = nn + x[i], yy = mm + y[i];
if (xx >= 1 && xx <= n&&yy >= 1 && yy <= m)
{
if (mmp[xx][yy])cnt++;
}
}
if (cnt > K )return false;
return true;
}
}
void print()
{
printf("--------------------------------------\n");
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
printf("%d", mmp[i][j]);
}
printf("\n");
}
}
void DFS(int nx, int ny, int now, int last)///盲猜last剩余炸弹,now已填炸弹
{
if (now + last <= ans)return;
///如果这个递归填的数目和最大理想填雷数目都比ans小,就不需要递归了
if (nx>n)///盲猜此时n*m已遍历完整个矩阵
{
if (check(n, m) && check(n - 1, m))
{
ans = max(ans, now);
//print();
}
return;
}
for (int i = 0; i <= 1; i++) ///填完后,左上角的点必满足四周都有点
///只检查左上角的点便可
{
mmp[nx][ny] = i;///雷或空位
//print();
if (nx == n)
{
if (check(nx - 1, ny - 1) && check(nx, ny - 1))
{
if (ny == m&&check(nx - 1, m))DFS(nx + 1, 1, now + i, last - 1);
else DFS(nx, ny + 1, now + i, last - 1);
}
}
else if (ny == m)
{
if (check(nx - 1, ny - 1) && check(nx - 1, ny))
{
DFS(nx + 1, 1, now + i, last - 1);
}
}
else if (check(nx - 1, ny - 1))
{
DFS(nx, ny + 1, now + i, last - 1);///盲猜失败
///now是已填雷,last是剩余空间
}
}
return;
}
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%d %d %d", &n, &m, &K);
memset(mmp, inf, sizeof(mmp));
ans = 0;
DFS(1, 1, 0, n*m);
printf("%d\n", ans);
}
getchar();
getchar();
}