[BZOJ3109][CQOI2013]新数独(暴力Dfs)

    题面..复制不过来..去BZOJ上看吧QwQ。
    原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3109

思路&&分析:

    Emmm…这题其实没啥好讲的,只要有信仰打暴力打上去就能A了..只是需要加一点剪枝,就是每一行的最后一个可以根据前8个数的和算出而不需要1~9扫一遍,每一列的最后一个和每一块的最后一个也都是一样的,只要加了这三个剪枝就可以稳过了。

Code

#pragma GCC optimize(3)
#include
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
int ans[9][9],sum[9],row[9],col[9],liml[9][9],limr[9][9],line[9]={1,3,5,6,8,10,11,13,15},cnt=9,posi[6]={1,2,4,5,7,8},cnt2;
bool usec[9][10],user[9][10],uses[9][10],bigr[9][9],bigc[9][9];
inline int nxtx(int x,int y) {
    if(y==8)
        return x+1;
    return x;
}
inline int nxty(int x,int y) {
    if(y==8)
        return 0;
    return y+1;
}
inline void writeit() {
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
            printf("%d%c",ans[i][j],j==8?'\n':' ');
}
inline bool check() {
//  writeit();
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++) {
            if(i%3!=2)
                if(bigr[i][j]!=(ans[i][j]>ans[i+1][j]))
                    return 0;
            if(j%3!=2)
                if(bigc[i][j]!=(ans[i][j]>ans[i][j+1]))
                    return 0;
        }
    return 1;
}
inline void dfs(int x,int y) {
    int b=(x/3)*3+(y/3);
//  cerr<
//  writeit();
    if(x==9&&y==0) {
//      if(check()) {
            writeit();
            exit(0);
//      }
    }
    if(x%3==2&&y%3==2) {
        int i=45-sum[b];
        if(!usec[x][i]&&!user[y][i]&&!uses[b][i]) {
            if(x%3&&bigr[x][y]!=(i>ans[x-1][y]))
                return;
            if(y%3&&bigc[x][y]!=(i>ans[x][y-1]))
                return;
            usec[x][i]=user[y][i]=uses[b][i]=1;
            sum[b]+=i;row[y]+=i;col[x]+=i;ans[x][y]=i;
            dfs(nxtx(x,y),nxty(x,y));
            sum[b]-=i;row[y]-=i;col[x]-=i;ans[x][y]=0;
            usec[x][i]=user[y][i]=uses[b][i]=0;
        }
        return;
    }
    if(y==8) {
        int i=45-col[x];
        if(!usec[x][i]&&!user[y][i]&&!uses[b][i]) {
            if(x%3&&bigr[x][y]!=(i>ans[x-1][y]))
                return;
            if(y%3&&bigc[x][y]!=(i>ans[x][y-1]))
                return;
            usec[x][i]=user[y][i]=uses[b][i]=1;
            sum[b]+=i;row[y]+=i;col[x]+=i;ans[x][y]=i;
            dfs(nxtx(x,y),nxty(x,y));
            sum[b]-=i;row[y]-=i;col[x]-=i;ans[x][y]=0;
            usec[x][i]=user[y][i]=uses[b][i]=0;
        }
        return;
    }
    if(x==8) {
        int i=45-row[y];
        if(!usec[x][i]&&!user[y][i]&&!uses[b][i]) {
            if(x%3&&bigr[x][y]!=(i>ans[x-1][y]))
                return;
            if(y%3&&bigc[x][y]!=(i>ans[x][y-1]))
                return;
            usec[x][i]=user[y][i]=uses[b][i]=1;
            sum[b]+=i;row[y]+=i;col[x]+=i;ans[x][y]=i;
            dfs(nxtx(x,y),nxty(x,y));
            sum[b]-=i;row[y]-=i;col[x]-=i;ans[x][y]=0;
            usec[x][i]=user[y][i]=uses[b][i]=0;
        }
        return;
    }
    for(int i=1;i<=9;i++) {
        if(!usec[x][i]&&!user[y][i]&&!uses[b][i]&&sum[b]+i<=45&&row[y]+i<=45&&col[x]+i<=45) {
            if(x%3&&bigr[x][y]!=(i>ans[x-1][y]))
                continue;
            if(y%3&&bigc[x][y]!=(i>ans[x][y-1]))
                continue;
            usec[x][i]=user[y][i]=uses[b][i]=1;
            sum[b]+=i;row[y]+=i;col[x]+=i;ans[x][y]=i;
            dfs(nxtx(x,y),nxty(x,y));
            sum[b]-=i;row[y]-=i;col[x]-=i;ans[x][y]=0;
            usec[x][i]=user[y][i]=uses[b][i]=0;
        }
    }
}
int main() {
//  freopen("input.txt","r",stdin);
//  freopen("check.out","w",stdout);
    for(int i=1;i<=15;i++) {
        char op[2];int pos=lower_bound(line,line+cnt,i)-line;
        if(line[pos]==i) {
            for(int j=0;j<6;j++) {
                scanf("%s",op);
                if(op[0]=='<')
                    bigc[pos][posi[j]]=1;
                else
                    bigc[pos][posi[j]]=0;
            }
        }
        else {
            for(int j=0;j<9;j++) {
                scanf("%s",op);
                if(op[0]=='^')
                    bigr[posi[cnt2]][j]=1;
                else
                    bigr[posi[cnt2]][j]=0;
            }
            cnt2++;
        }
    }
//  for(int i=0;i<9;i++)
//      for(int j=0;j<9;j++)
//          printf("%c%c",j%3==0?' ':!bigc[i][j]?'>':'<',j==8?'\n':' ');
//  cout<<"========================="<
//  for(int i=0;i<9;i++)
//      for(int j=0;j<9;j++)
//          printf("%c%c",i%3==0?' ':!bigr[i][j]?'v':'^',j==8?'\n':' ');
//  cout<<"========================="<
    dfs(0,0);
}

你可能感兴趣的:(技巧)