zoukankan      html  css  js  c++  java
  • Sudoku

    POJ 数据弱

    POJ 数据强

    题意:数独不解释了.两道题的输入输出有点差别,自己看一下题面.

    分析:对每一行,每一列,每个格子都用一个九位的二进制数表示,初始化每一位都为1,然后每一次从状态最少的开始搜索,对于一个点((i,j)),(val=line[i])&(lie[j])&(ge[(i/3)*3+j/3]),则val是可以填的.

    下面放的是3074的代码.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    int hang[10],lie[10],ge[10],sum[1000];
    char s[100],ch[10][10];
    inline void get_bj(int x,int y,int z){
    	hang[x]^=(1<<z);
    	lie[y]^=(1<<z);
    	ge[(x/3)*3+y/3]^=(1<<z);
    }
    inline bool dfs(int now){
    	if(!now)return 1;//填完了
    	int maxn=10,x,y;
    	for(int i=0;i<9;++i)
    		for(int j=0;j<9;++j){
    			if(ch[i][j]!='.')continue;
    			int val=hang[i]&lie[j]&ge[(i/3)*3+j/3];
    			if(!val)return 0;//如果这一位要填数,却没东西填,则说明此次搜索失败
    			if(sum[val]<maxn){//找到最少的可以填的地方
    				maxn=sum[val];
    				x=i;y=j;
    			}
    		}
    	int val=hang[x]&lie[y]&ge[(x/3)*3+y/3];
    	for(int j=0;j<9;++j)
    		if(val&(1<<j)){
    			ch[x][y]='1'+j;get_bj(x,y,j);
    			if(dfs(now-1))return 1;
    			ch[x][y]='.';get_bj(x,y,j);//回溯
    		}
    	return 0;
    }
    int main(){
    	for(int i=0;i<(1<<9);++i)
    		for(int j=0;j<9;++j)
    			if(i&(1<<j))++sum[i];//预处理每个二进制数有几个1
    	while(~scanf("%s",s)&&s[0]!='e'){
    		for(int i=0;i<9;++i)
    			for(int j=0;j<9;++j)ch[i][j]=s[i*9+j];
    		for(int i=0;i<9;i++)hang[i]=lie[i]=ge[i]=(1<<9)-1;//初始化,每一位都为1
    		int tot=0;
    		for(int i=0;i<9;++i)
    			for(int j=0;j<9;++j){
    				if(ch[i][j]=='.')++tot;
    				else get_bj(i,j,ch[i][j]-'1');
    			}
    		dfs(tot);//要填tot个格子
    		for(int i=0;i<9;++i)
    			for(int j=0;j<9;++j)s[i*9+j]=ch[i][j];
    		puts(s);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    调用Type.InvokeMember()时出现MissingMethodException
    C#学习之Delegate
    WCF之元数据交换 (Metadata Exchange)
    定义Enum的开始和结束,这样就能循环Enum了
    定制自己的Visual Studio的Debugger Visualizer
    C#中 #if DEBUG 和 Conditional("DEBUG")的区别
    从哪里开始学习Windows 8?(zz)
    Macro 小总结
    WPF应用的图标
    如何把 Visutal studio中的“printonbreakpoint”消息打印在程序的任何地方
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11354615.html
Copyright © 2011-2022 走看看