扫雷算法

所谓扫雷首先一个简单只有一行啊 a[i]=a[i-1]-vis[i-1]-vis[i-2]

通过二元一次方程 正推

#include<bits/stdc++.h>
using namespace std;
#define LOACL  freopen("in","r",stdin);\
            freopen("out","w",stdout); 

const int  inf = 987654321;
const int sz = 1e6 + 5;
const int mod = 1e9 + 7;
const int sqrtn = 300; 

#define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
#define f(i,l,r) for(int i=l;i<=r;++i)
#define g(i,l,r) for(int i=l;i>=r;--i)
#define CLR(arr,val) memset(arr,val,sizeof(arr)) 
typedef long long ll; 
int n,a [2][sz];
int arr[sz],b0[sz],b1[sz],ans0[sz],ans1[sz];
bool f0,f1;
void slove()
{
    f0=f1=true;
    b0[1]=0;
    b0[1]=1;
    f(i,2,n)
    {
        if(f0)
        {
            b0[i]=arr[i-1]-b0[i-1]-b0[i-2];
            if(b0[i]<0||b0[i]>1)f0=false;
        }
        if(f1)
        {
            b1[i]=arr[i-1]-b1[i-1]-b1[i-2];
            if(b1[i]<0||b1[i]>1)f1=false;
        }
    }
    if(arr[n]!=b0[n]+b0[n-1])
        f0=false;
    if(arr[n]!=b1[n]+b1[n-1])
        f1=false;
    
}
int main()
{
    LOACL
    int t;
    cin>>t;
    while(t--)
    {
        CLR(a,0);

        cin>>n;
        f(i,1,n)cin>>arr[i];
        slove();
        int cnt0 =0,cnt1=0;
        if(f0  && f1)
        {
            f(i,1,n)
            {
                if(b0[i]==1 && b1[i]==1)
                {
                    ans1[cnt1++]=i ;
                }
                else if  (b0[i]==0 && b1[i]==0)    
                ans0[cnt0++]=i ;    
            }    
        }
        else if(  f1 )
        {
            f(i,1,n)
            if (b1[i] == 1)  
                ans1[cnt1++] = i;  
            else  
                ans0[cnt0++] = i;  
        }
        else if(  f0 )
        {
            f(i,1,n)
            if (b0[i] == 1)  
                ans1[cnt1++] = i;  
            else  
                ans0[cnt0++] = i;  
        }
        cout<<cnt1;
        f(i,0,cnt1-1)cout<<" "<<ans1[i];cout<<endl;
        cout<<cnt0;
        f(i,0,cnt0-1)cout<<" "<<ans0[i];cout<<endl;


    }
    return 0;
}
View Code

 

多维:

情况一 中心为0 四周都是安全区域

情况二: 中心数 等于 未知区域 那么都是地雷

情况三: 中心数 和其边缘的那个已知数字 满足 a-b= c(a)-c(b) 那么非交界都是雷

 #include<bits/stdc++.h>
 using namespace std;
 #define LOACL  freopen("in","r",stdin);\
             freopen("out","w",stdout); 
 
 const int  inf = 987654321;
 const int sz = 1e6 + 5;
 const int mod = 1e9 + 7;
 const int sqrtn = 300; 
 
 #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
 #define f(i,l,r) for(int i=l;i<=r;++i)
 #define g(i,l,r) for(int i=l;i>=r;--i)
 #define CLR(arr,val) memset(arr,val,sizeof(arr)) 
 typedef long long ll; 
 int n,m;
 int a[201][201];
 int cnt0,cnt1 ;
 int calc(int x,int y)
 {
     int count=0;
     f(i,-1,1) if(x+i>=1&&x+i<=n)
     f(j,-1,1) if(y+j>=1&&y+j<=m &&a[x+i][y+j] <0)
     count++;
     return count;
 }
 bool  isnxt(int x,int y,int i,int j)
 {
     if((x-i)>1||(x-i)<-1||(y- j)>1||(y- j)<-1) return  false;
     return true ;
 }
 
  
  bool check(int x,int y,int c,int d)
 {
     f(i,-1,1) if(x+i>=1&&x+i<=n)
     f(j,-1,1) if(y+j>=1&&y+j<=m &&a[x+i][y+j] < 0 &&!isnxt(x+i,y+j,c,d))
     return false ;
     return true;
 }
 void run(int x,int y)
 {
     f(i,-1,1) if(x+i>=1&&x+i<=n)
     f(j,-1,1) if(y+j>=1&&y+j<=m &&a[x+i][y+j] == -1)
     a[x+i][y+j] =-2;
 } 
 void run2(int x,int y)
 {
     if(calc(x,y)==a[x][y])
     f(i,-1,1) if(x+i>=1&&x+i<=n)
     f(j,-1,1) if(y+j>=1&&y+j<=m &&a[x+i][y+j] <0 )
     a[x+i][y+j] =-3;
 } 
 void run3(int x,int y)
 {
     f(c,-2,2)  if(x+c>=1&&x+c<=n)
    f(d,-2,2) 

    if(y+d>=1&&y+d<=m && (c||d)&&a[x+c][y+d]>=0 && check(x+c,y+d,x,y))
    {
        if(a[x][y]-a[x+c][y+d] == calc(x,y)-calc(x+c,y+d))
        {
                f(i,-1,1) if(x+i>=1&&x+i<=n)
                 f(j,-1,1) if(y+j>=1&&y+j<=m && a[x+i][y+j]<0 &&!isnxt(x+i,y+j,x+c,y+d))
                 a[x+i][y+j] =-3;
        }
    }
 }
  
 int main()
 {
     LOACL
     int t;
     cin>>t;
     while(t--)
     {
         cin>>n>>m;
         f(i,1,n) f(j,1,m) cin>>a[i][j];
         f(i,1,n) f(j,1,m)
         {
             if(!a[i][j])run(i,j);
             if(a[i][j]>0) run2(i,j),run3(i,j);
         }
         cnt0=cnt1=0;
         f(i,1,n) f(j,1,m)
         {
             if(a[i][j]==-2) cnt0++;
             if(a[i][j]==-3) cnt1++; 
         }
         cout<<cnt1<<" "<<cnt0<<endl;
     }     
     return 0;
 }
View Code

 

转载于:https://www.cnblogs.com/corx/p/8569636.html

根据提供的引用内容,扫雷算法可以使用Python中的字典、集合、元组和列表来实现。具体的实现方法可以根据不同的需求和规则进行设计。以下是一个简单的扫雷算法的示例: ```python # 扫雷算法示例 def mine_sweeper(board, click): # 定义方向数组,用于表示周围8个方向的偏移量 directions = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)] m, n = len(board), len(board[0]) def dfs(x, y): # 终止条件 if x < 0 or x >= m or y < 0 or y >= n or board[x][y] != 'E': return # 计算周围的地雷数量 count = 0 for dx, dy in directions: nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n and board[nx][ny] == 'M': count += 1 # 如果周围有地雷,则更新当前位置的值为地雷数量,并停止继续搜索 if count > 0: board[x][y] = str(count) return # 如果周围没有地雷,则将当前位置标记为已搜索,并继续搜索周围的位置 board[x][y] = 'B' for dx, dy in directions: nx, ny = x + dx, y + dy dfs(nx, ny) # 点击的位置是地雷,则直接返回 if board[click[0]][click[1]] == 'M': board[click[0]][click[1]] = 'X' else: dfs(click[0], click[1]) return board # 示例用法 board = [['E', 'E', 'E', 'E', 'E'], ['E', 'E', 'M', 'E', 'E'], ['E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E']] click = [3, 0] result = mine_sweeper(board, click) for row in result: print(row) ``` 这个示例中,我们使用深度优先搜索算法来实现扫雷功能。首先判断点击的位置是否是地雷,如果是地雷则直接返回,否则从点击的位置开始进行深度优先搜索,计算周围的地雷数量并更新当前位置的值。如果周围没有地雷,则将当前位置标记为已搜索,并继续搜索周围的位置。最后返回更新后的扫雷板。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值