zoukankan      html  css  js  c++  java
  • 5 October

    POJ2676 Sudoku

    位运算 + 搜索。更好的优化方法:方案数最小的空格先填。

    把某一位 置为 0a &=~ (1<<n)

    把某一位 置为 1a |= (1<<n)

    #include <cstdio>
    #include <cstring>
    int T, f[9], g[9], h[3][3];
    char buf[10]; 
    int v[9][9], tot;
    
    inline int lowbit(int x) { return x&(-x); }
    inline int num(int x) {
    	register int cnt=0; while (x) ++cnt, x>>=1; return cnt-1;
    }
    
    bool search(int x, int y) {
    	int res=f[x]&g[y]&h[x/3][y/3];
    	if (!res) return 0;
     	while (res) {
    		int t=lowbit(res); res&=~t; --tot;
    		f[x]&=~t, g[y]&=~t, h[x/3][y/3]&=~t; v[x][y]=num(t);
    		if (!tot) return 1;
    		for (int i=0, bk=0; i<9; ++i) {
    			for (int j=0; j<9; ++j)
    				if (!v[i][j]) {if (search(i, j)) return 1; bk=1; break; }
    			if (bk) break;
    		}
    		f[x]|=t, g[y]|=t, h[x/3][y/3]|=t; v[x][y]=0; ++tot;
    	}
    	return 0;
    }
    
    int main() {
    	scanf("%d", &T);
    	while (T--) {
    		for (int i=0; i<9; ++i) for (int j=0; j<9; ++j)
    			f[i]=g[i]=(1<<10)-2;
    		for (int i=0; i<3; ++i) for (int j=0; j<3; ++j) 
    			h[i][j]=(1<<10)-2;
    		memset(v, 0, sizeof v); tot=0;
    		for (int i=0; i<9; ++i) {
    			scanf("%s", buf);
    			for (int j=0; j<9; ++j) if (buf[j]-='0') {
    				v[i][j]=buf[j];
    				f[i]&=~(1<<buf[j]), g[j]&=~(1<<buf[j]),
    				h[i/3][j/3]&=~(1<<buf[j]);
    			} else ++tot;
    		}
    		for (int i=0, bk=0; i<9; ++i) {
    			for (int j=0; j<9; ++j)
    				if (!v[i][j]) {search(i, j); bk=1; break; }
    			if (bk) break;
    		}
    		for (int i=0; i<9; ++i) {
    			for (int j=0; j<9; ++j) printf("%d", v[i][j]);
    			printf("
    ");
    		}
    	}
    	return 0;
    } 
    
  • 相关阅读:
    JZ2440开发板开发环境搭建
    20180730-宿主机开发环境搭建
    20180319-双网卡电脑同时上内外网
    嵌入式ARM板子起步
    20180127-服务器开发环境搭建
    Pool多进程示例
    Python基础-day01
    解释型语言与编译型语言
    C 编译过程浅析
    博客奇谭
  • 原文地址:https://www.cnblogs.com/greyqz/p/11625309.html
Copyright © 2011-2022 走看看