hdu1426 hdu3111 poj2676回溯法解数独

hdu1426 注意输入输出格式,行列判断的下标

#include<bits/stdc++.h>
using namespace std;
/* hdu1426 解数独,回溯法,注意格式
   0: 0  1  2  3  4  5  6  7  8 
   1: 9  10 11 12 13 14 15 16 17
   2: 18 19 20 ......
 */
vector< pair<int,int> >v;
vector< vector<int> >mp;

bool dfs(int now,int num){
    if(num==now){
        for(int i=0;i<9;i++){
            cout<<mp[i][0];
            for(int j=1;j<9;j++)
                cout<<" "<<mp[i][j];
            puts("");
        }
        return true;
    }
    int x=v[now].first;
    int y=v[now].second;
    for(int i=1;i<=9;i++){
        int fl=1;
        for(int j=0;j<9;j++){//列行判断
            if(mp[x][j]==i||mp[j][y]==i){
                fl=0;break;
            }
        }
        for(int j=x/3*3;j<=x/3*3+2;j++){//9宫格判断
            for(int z=y/3*3;z<=y/3*3+2;z++){
                if(mp[j][z]==i){
                    fl=0;break;
                } 
            }
        }
        if(fl==0)continue;
        mp[x][y]=i;
        if(dfs(now+1,num))return true;
        mp[x][y]=0;//回溯

    }
    return false;

}

int main(){
    string s;int cnt=0;int num=0;int T=0;
    while(getline(cin,s)){
        if(s.size()==0||s.size()==1)continue;
        vector<int>t;
        for(int i=0;i<s.size();i++){
            if(s[i]=='?')t.push_back(0),v.push_back(make_pair(cnt,i/2)),num++;//问号个数
            else if(s[i]>'0'&&s[i]<='9')t.push_back(s[i]-'0');
        }
        mp.push_back(t);
        cnt++;
        if(cnt==9){
            if(T++)puts("");//该死的PE
            dfs(0,num);
            num=0;cnt=0;v.clear();mp.clear();
        }
    }
    system("pause");
}

hdu3111 同hdu1426,改下输入输出格式

#include<bits/stdc++.h>
using namespace std;
/* hdu3111 解数独,回溯法,注意格式
   0: 0  1  2  3  4  5  6  7  8 
   1: 9  10 11 12 13 14 15 16 17
   2: 18 19 20 ......
 */
vector< pair<int,int> >v;
vector< vector<int> >mp;

bool dfs(int now,int num){
    if(num==now){
        for(int i=0;i<9;i++){
            cout<<mp[i][0];
            for(int j=1;j<9;j++)
                cout<<mp[i][j];
            puts("");
        }
        return true;
    }

    int x=v[now].first;
    int y=v[now].second;

    for(int i=1;i<=9;i++){
        int fl=1;
        for(int j=0;j<9;j++){//列行判断
            if(mp[x][j]==i||mp[j][y]==i){
                fl=0;break;
            }
        }
        for(int j=x/3*3;j<=x/3*3+2;j++){//9宫格判断
            for(int z=y/3*3;z<=y/3*3+2;z++){
                if(mp[j][z]==i){
                    fl=0;break;
                } 
            }
        }
        if(fl==0)continue;
        mp[x][y]=i;
        if(dfs(now+1,num))return true;
        mp[x][y]=0;//回溯

    }
    return false;

}

int main(){
    string s;int cnt=0;int num=0;int T=0;int Q=0;
    cin>>Q;
    while(1){
        getline(cin,s);
        if(s.size()<=4)continue;
        vector<int>t;
        for(int i=0;i<s.size();i++){
            if(s[i]=='?')t.push_back(0),v.push_back(make_pair(cnt,i)),num++;//问号个数
            else if(s[i]>'0'&&s[i]<='9')t.push_back(s[i]-'0');
        }
        mp.push_back(t);
        cnt++;
        if(cnt==9){
            if(T++)puts("---");//该死的PE
            if(!dfs(0,num))puts("impossible");
            if(T==Q)break;
            num=0;cnt=0;v.clear();mp.clear();
        }
    }
    system("pause");
}

poj2676 需要分别记录行列九宫格已经有的数字来减少每一层的枚举量

注意下标的映射

#include<iostream>
#include<string.h>
#include<vector>
#include<stdio.h>
using namespace std;
/* hdu3111 解数独,回溯法,注意格式
   0: 0  1  2  3  4  5  6  7  8 
   1: 9  10 11 12 13 14 15 16 17
   2: 18 19 20 ......
 */
vector< pair<int,int> >v;
vector< vector<int> >mp;
int row[10][10];//行i数字j是否出现   空间换时间
int col[10][10];//列i数字j是否出现
int fck[10][10];//九宫格第i块数字j是否出现
bool dfs(int now,int num){
    if(num==now){
        for(int i=0;i<9;i++){
            cout<<mp[i][0];
            for(int j=1;j<9;j++)
                cout<<mp[i][j];
            puts("");
        }
        return true;
    }

    int x=v[now].first;
    int y=v[now].second;
    int bl=x/3*3+y/3;
    for(int i=1;i<=9;i++){
        if(col[x][i]||row[y][i]||fck[bl][i])continue;
        mp[x][y]=i;
        col[x][i]=1;
        row[y][i]=1;
        fck[bl][i]=1;

        if(dfs(now+1,num))return true;
        mp[x][y]=0;//回溯
        col[x][i]=0;
        row[y][i]=0;
        fck[bl][i]=0;

    }
    return false;

}

int main(){
    string s;int cnt=0;int num=0;int T=0;int Q=0;
    cin>>Q;
    while(1){
        getline(cin,s);
        if(s.size()<=4)continue;
        vector<int>t;
        for(int i=0;i<s.size();i++){
            if(s[i]=='0')t.push_back(0),v.push_back(make_pair(cnt,i)),num++;//问号个数
            else if(s[i]>'0'&&s[i]<='9'){
                col[cnt][s[i]-'0']=1;
                row[i][s[i]-'0']=1;
                fck[cnt/3*3+i/3][s[i]-'0']=1;
                t.push_back(s[i]-'0');
            }
        }
        mp.push_back(t);
        cnt++;
        if(cnt==9){
            if(T++)puts("");//该死的PE
            if(!dfs(0,num))puts("impossible");
            if(T==Q)break;
            num=0;cnt=0;v.clear();mp.clear();
            memset(row,0,sizeof(row));
            memset(col,0,sizeof(col));
            memset(fck,0,sizeof(fck));
        }
    }
    //system("pause");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值