数字游戏

题目:

 

 

 

 

 

 

 

 这道题目是一点数学成分+一点DFS

主要介绍DFS以及其调用的变量

DFS:dfs(x,y,dir,rem,d_t)

1.DFS变量介绍

(x,y):出发x,y坐标

dir:向对于整个地图来说的dir方向走,向上为0,向下为1,向左为2,向右为3。一定要记住所有的方向值一定是对于整个地图的(非局部)!

rem:累积的数mod7的值,由于此题目v[i][j]值比较大再合并之后就有很大概率中奖🎰,所以在更新rem时需要根据(a+b)%c=(a%c+b%c)%c将先拼后mod的思路改为一直mod尽可能不中奖!

d_t:剩下的可以转向的次数,每次转弯时需要-1.

2.全局变量:

v[i][j]:被输入的在地图上 i   j  点的值

b[i][j]:v[i][j]的位数

qpow[i]:10^i mod 7的值

vis[i][j]:(i,j)点有没有访问过,初始化要清空vis数组!

3.DFS重点:

3.1 开始DFS时要用两个子程序👇,因为开始被堵墙角只有两条路可以选因为我们可爱的DFS帮不了忙,就勉为其难的用两个字程序吧。

    dfs(1,1,3,v[1][1]%7,k);
    dfs(1,1,1,v[1][1]%7,k-1);

 3.2 按照4个方向分别写四个程序片段,以向上 dir=0为例介绍如下:

    if(dir==0) //up   x   -1
    {
        int nx=0,nr=rem;
        for(nx=x-1;nx>=1;nx--) //枚举他能走到哪些地方,nx持续--,y不变
        {
            if(vis[nx][y]==1) break; //如果此点已被经过,退出。
            nr=((nr*qpow[b[nx][y]])%7+v[nx][y]%7)%7; //更新nr(new_rem)值
            if(nr==0) ans++;//如果nr满足要求计数器ans++;
            vis[nx][y]=1;//标记(nx,y)已被经过
            if(d_t>0)//还可以转向
            {
                if(y<m) dfs(nx,y,3,nr,d_t-1);//可以向右转
                if(y>1) dfs(nx,y,2,nr,d_t-1);//可以向左转
            }
        }
        for(nx++;nx<x;nx++) vis[nx][y]=0;//回溯vis   先加nx是因为前面循环结束后nx<1需要先加回来
    }
    

 

 

 

飙程:

#include<bits/stdc++.h>
using namespace std;
const int N=1000;
int n,m,k;
long long b[N][N]={0},v[N][N]={0},qpow[N]={0},vis[N][N]={0},ans=0;
void dfs(int x,int y,int dir,int rem,int d_t)
{
    
    if(dir==0)//up   x   -1
    {
        int nx=0,nr=rem;
        for(nx=x-1;nx>=1;nx--)
        {
            if(vis[nx][y]==1) break;
            nr=((nr*qpow[b[nx][y]])%7+v[nx][y]%7)%7;
            if(nr==0) ans++;
            vis[nx][y]=1;
            if(d_t>0)
            {
                if(y<m) dfs(nx,y,3,nr,d_t-1);
                if(y>1) dfs(nx,y,2,nr,d_t-1);
            }
        }
        for(nx++;nx<x;nx++) vis[nx][y]=0;
    }
    
    if(dir==1)//down   x   +1
    {
        int nx=0,nr=rem;
        for(nx=x+1;nx<=n;nx++)
        {
            if(vis[nx][y]==1) break;
            nr=((nr*qpow[b[nx][y]])%7+v[nx][y]%7)%7;
            if(nr==0) ans++;
            vis[nx][y]=1;
            if(d_t>0)
            {
                if(y<m) dfs(nx,y,3,nr,d_t-1);
                if(y>1) dfs(nx,y,2,nr,d_t-1);
            }
        }
        for(nx--;nx>x;nx--) vis[nx][y]=0;
    }
    
    if(dir==2)//left   y   -1
    {
        int ny=0,nr=rem;
        for(ny=y-1;ny>=1;ny--)
        {
            if(vis[x][ny]==1) break;
            nr=((nr*qpow[b[x][ny]])%7+v[x][ny]%7)%7;
            if(nr==0) ans++;
            vis[x][ny]=1;
            if(d_t>0)
            {
                if(x<n) dfs(x,ny,1,nr,d_t-1);
                if(x>1) dfs(x,ny,0,nr,d_t-1);
            }
        }
        for(ny++;ny<y;ny++) vis[x][ny]=0;
    }
    
    if(dir==3)//right   y   +1
    {
        int ny=0,nr=rem;
        for(ny=y+1;ny<=m;ny++)
        {
            if(vis[x][ny]==1) break;
            nr=((nr*qpow[b[x][ny]])%7+v[x][ny]%7)%7;
            if(nr==0) ans++;
            vis[x][ny]=1;
            if(d_t>0)
            {
                if(x<n) dfs(x,ny,1,nr,d_t-1);
                if(x>1) dfs(x,ny,0,nr,d_t-1);
            }
        }
        for(ny--;ny>y;ny--) vis[x][ny]=0;
    }
}
int main()
{
#ifdef LOCAL
 freopen( "1.in", "r", stdin );
 freopen( "1.out", "w", stdout );
#endif
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&v[i][j]);
            int t=v[i][j];
            while(t)
            {
                b[i][j]++;
                t/=10;
            }
        }
    }
    qpow[0]=1;
    for(int i=1;i<20;i++) qpow[i]=(long long)qpow[i-1]*10%7;
    if(v[1][1]%7==0) ans++;
    vis[1][1]=1;
    dfs(1,1,3,v[1][1]%7,k);
    dfs(1,1,1,v[1][1]%7,k-1);
    cout<<ans;
    return 0;
}

 

posted @ 2022-10-02 23:13  王浩泽  阅读(176)  评论(0编辑  收藏  举报