zoukankan      html  css  js  c++  java
  • 靶形数独

    题目描述

    思路

    一开始,觉得应该对每个格子为0的进行dfs,为了进行顺序最优的dfs,要先从可选数量少的格子进行,这样对每个格子创建一个set,存储能够填的数。
    然后就是根据size大小排序,选择最小的进行dfs。
    然后发现每次dfs都要进行排序,set的二维数组得设在dfs函数内,排序的时候又得根据这个set数组的大小进行排序,对于cmp函数内访问的set应该是全局变量,又得设置一个全局变量的set二维数组保存每次dfs函数内创建的set数组,然后排序。
    然后发现每次dfs只会选择数据量最小的进行排序,这样就不用使用二维数组,直接遍历的时候筛选处数据量最小的set就可以了。
    然后就是这样做了之后,忘记判断有无解的情况,之后就是wrong answeer。
    然后就是time limit exceed,按照书上说的dfs剪枝技巧,最起码现在完成了最优搜索顺序。
    然后就是每次填数字其实影响的就只有行,列和小九宫格里面的数据选择,更新全部的话,显得重复,不更新全部,代码有点难写。dfs就麻烦在剪枝上,剪不掉就会造成超时,真烦人。
    然后就是可以采用状态压缩的方式保存格子的数据选择集合。
    然后就是去掉set,改用位运算的方式实现上述的算法,终于过了,可见set是多么的耗时。

    代码

    #include <cstdio>
    #include <cstring>
    
    int mp[9][9], ans;
    const int wq = 511;
    bool flag = false;
    int val[9][9] = {
    	6, 6, 6, 6, 6, 6, 6, 6, 6, 
    	6, 7, 7, 7, 7, 7, 7, 7, 6, 
    	6, 7, 8, 8, 8, 8, 8, 7, 6,
    	6, 7, 8, 9, 9, 9, 8, 7, 6, 
    	6, 7, 8, 9,10, 9, 8, 7, 6,
    	6, 7, 8, 9, 9, 9, 8, 7, 6,
    	6, 7, 8, 8, 8, 8, 8, 7, 6,
    	6, 7, 7, 7, 7, 7, 7, 7, 6,
    	6, 6, 6, 6, 6, 6, 6, 6, 6, 
    };
    bool get(int x, int y, int &z) {
    	int k = 0;
    	for (int i = 0; i < 9; ++i) {
    		if (mp[x][i] != 0) k |= 1 << (mp[x][i] - 1);
    		if (mp[i][y] != 0) k |= 1 << (mp[i][y] - 1);
    	}
    	int a = x / 3 * 3, b = y / 3 * 3;
    	for (int i = 0; i < 3; ++i) {
    		for (int j = 0; j < 3; ++j) {
    			if (mp[a + i][b + j] != 0) k |= 1 << (mp[a + i][b + j] - 1);
    		}
    	}
    	z = wq ^ k;
    	return z == 0;
    }
    
    int getbit(int x) {
    	int y = 0;
    	while (x) {
    		if (x & 1) ++y;
    		x >>= 1;
    	}
    	return y;
    }
    bool mysort(int &x, int &y, int &z) {
    	z = wq;
    	int b = 0;
    	for (int i = 0; i < 9; ++i) {
    		for (int j = 0; j < 9; ++j) {
    			if (mp[i][j] == 0) {
    				if (get(i, j, b)) return false;
    				if (getbit(b) < getbit(z)) z = b, x = i, y = j;
    			}
    		}
    	}
    	return true;
    }
    
    void dfs(int res) {
    	int x, y, z = 0;
    	if (!mysort(x, y, z)) return;
    	if (getbit(z) == 9) {
    		flag = true;
    		if (res > ans) ans = res;
    		return;
    	}
    	int k = 0;
    	while (z) {
    		if (z & 1) {
    			mp[x][y] = k + 1;
    			dfs(res + mp[x][y] * val[x][y]);
    			mp[x][y] = 0;
    		}
    		z >>= 1;
    		k++;
    	}
    }
    int main() {
    	for (int i = 0; i < 9; ++i) {
    		for (int j = 0; j < 9; ++j) {
    			scanf("%d", &mp[i][j]);
    			if (mp[i][j] != 0) ans += mp[i][j] * val[i][j];
    		}
    	}
    	dfs(ans);
    	if (flag) printf("%d
    ", ans);
    	else puts("-1");
    	return 0;
    }
    
  • 相关阅读:
    删除前添加确认删除弹出框
    virtualbox 网络设置
    JavaScript跨域总结与解决办法
    分享一个ci 框架下取不到cookie的问题
    firebug console说明
    innodb 修改表共享空间为独立空间
    grunt 试用笔记
    apache TIME_WAIT解决办法
    负载均衡情况下获取真实ip的方法
    linux挂载硬盘
  • 原文地址:https://www.cnblogs.com/liuzz-20180701/p/11612567.html
Copyright © 2011-2022 走看看