数字游戏
题目:
这道题目是一点数学成分+一点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; }