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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值