2018湖南省赛_B
newcode
dfs的时候,先想搜的是什么。
1.规定——每次都搜待搜索的点
2.dfs进去后先写边界条件
3.还原现场
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100,Mod=1e9+7;
int cnt=0;
int num[5]={0,2018,1009,2,1};
int a[N][N];
int ans[N][N];
int dp[2002][2002];
int n,m;
//搞清dfs的含义
//待搜索的点,每个点可以放什么数
void dfs(int x,int y)
{
if(x>n){ //定义出界条件
cnt++; //一旦找到这里,说明找到了一种把所有点都填满数的方案,方案数+1
return;
}
if(x==1 && y==1){
a[1][1]=2018; //(1,1)已经放好数了,接下来搜索下一个位置
if(y!=m)dfs(x,y+1);
else dfs(x+1,y);
}
else if(x==1){
for(int i=1;i<=4;i++){
if(a[x][y-1]%num[i]==0 && !a[x][y]){ //满足约数条件 && 这个位置还没有搜索过
a[x][y]=num[i];
if(y!=m) dfs(x,y+1); //存在一个拐弯问题,所以这里要判断一下y现在在那里,以便确定接下来搜那个点,真正的出界的判断在dfs头,这里只是一个拐弯判断,dfs(x+1,y)一样可能出界,所以以后把出界条件定义在头
else dfs(x+1,1); //搜索顺序:先一直向右,到头去一行的头在一直向右搜
a[x][y]=0; //还原现场,现场就是0
}
}
}
else if(y==1){
for(int i=1;i<=4;i++){
if(a[x-1][y]%num[i]==0 && !a[x][y]){
a[x][y]=num[i];
if(y!=m) dfs(x,y+1);
else dfs(x+1,1);
a[x][y]=0;
}
}
}
else if(x<=n && y<=m){
for(int i=1;i<=4;i++){
if(a[x-1][y]%num[i]==0 && a[x][y-1]%num[i]==0 && !a[x][y]){
a[x][y]=num[i];
if(y!=m) dfs(x,y+1);
else dfs(x+1,1);
a[x][y]=0;
}
}
}
}
int main()
{
//打表
for(int i=1;i<=5;i++)
{
for(int j=1;j<=5;j++)
{
n=i,m=j;
cnt=0;
dfs(1,1);
printf("%3.0lf ",sqrt(cnt));
}
cout<<endl;
}
/*
for(int i=1;i<=2000;i++)
dp[1][i]=i;
for(int i=2;i<=2000;i++)
for(int j=1;j<=2000;j++)
dp[i][j]=(dp[i-1][j]+dp[i][j-1]+1)%Mod;
while(cin>>n>>m)
cout<<(1LL*dp[n][m]%Mod*dp[n][m]%Mod)%Mod<<endl; //1LL:long long类型的1相当于把后面的东西转换成long long类型 与1.0*x 把x转换成double类型一个意思
*/
return 0;
}