E. Minesweeper(dfs)——东三

还没时间写思路思想…先挂着

#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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值