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

    传送门
    Luogu

    解题思路

    这题其实挺简单的。
    首先要熟悉数独,我们应该要优先搜索限制条件多的行,也就是可能方案少的行,显然这样可以剪枝,然后再发挥一下dfs的基本功就可以了。

    细节注意事项

    • 爆搜题,你们都懂。。。

    参考代码

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cctype>
    #include <cmath>
    #include <ctime>
    #define rg register
    using namespace std;
    template < typename T > inline void read(T& s) {
    	s = 0; int f = 0; char c = getchar();
    	while (!isdigit(c)) f |= c == '-', c = getchar();
    	while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    	s = f ? -s : s;
    }
    
    const int s[10][10] = {
    	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    	{ 0, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
    	{ 0, 6, 7, 7, 7, 7, 7, 7, 7, 6 },
    	{ 0, 6, 7, 8, 8, 8, 8, 8, 7, 6 },
    	{ 0, 6, 7, 8, 9, 9, 9, 8, 7, 6 },
    	{ 0, 6, 7, 8, 9,10, 9, 8, 7, 6 },
    	{ 0, 6, 7, 8, 9, 9, 9, 8, 7, 6 },
    	{ 0, 6, 7, 8, 8, 8, 8, 8, 7, 6 },
    	{ 0, 6, 7, 7, 7, 7, 7, 7, 7, 6 },
    	{ 0, 6, 6, 6, 6, 6, 6, 6, 6, 6 }
    };
    
    const int p[10][10] = {
    	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    	{ 0, 1, 1, 1, 2, 2, 2, 3, 3, 3 },
    	{ 0, 1, 1, 1, 2, 2, 2, 3, 3, 3 },
    	{ 0, 1, 1, 1, 2, 2, 2, 3, 3, 3 },
    	{ 0, 4, 4, 4, 5, 5, 5, 6, 6, 6 },
    	{ 0, 4, 4, 4, 5, 5, 5, 6, 6, 6 },
    	{ 0, 4, 4, 4, 5, 5, 5, 6, 6, 6 },
    	{ 0, 7, 7, 7, 8, 8, 8, 9, 9, 9 },
    	{ 0, 7, 7, 7, 8, 8, 8, 9, 9, 9 },
    	{ 0, 7, 7, 7, 8, 8, 8, 9, 9, 9 },	
    };
    
    struct node { int id, cnt; }a[10];
    inline bool cmp(const node& x, const node& y) { return x.cnt > y.cnt; }
    int ans = -1, mp[10][10]; bool Line[10][10], Clmn[10][10], Palc[10][10];
    
    inline void dfs(int i, int j, int line, int sum) {
    	if (line > 9) { ans = max(ans, sum); return; }
    	if (j == 10) { dfs(a[line + 1].id, 1, line + 1, sum); return ; }
    	if (mp[i][j]) { dfs(i, j + 1, line, sum); return; }
    	for (rg int x = 1; x <= 9; ++x) {
    		if (Line[i][x]) continue;
    		if (Clmn[j][x]) continue;
    		if (Palc[p[i][j]][x]) continue;
    		Line[i][x] = Clmn[j][x] = Palc[p[i][j]][x] = 1, mp[i][j] = x;
    		dfs(i, j + 1, line, sum + x * s[i][j]);
    		Line[i][x] = Clmn[j][x] = Palc[p[i][j]][x] = 0, mp[i][j] = 0;
    	}
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("in.in", "r", stdin);
    #endif
    	for (rg int i = 1; i <= 9; ++i) a[i].id = i;
    	int tmp = 0;
    	for (rg int i = 1; i <= 9; ++i)
    		for (rg int j = 1; j <= 9; ++j) {
    			int x; read(x), mp[i][j] = x;
    			if (x) Line[i][x] = 1, Clmn[j][x] = 1, Palc[p[i][j]][x] = 1, ++a[i].cnt, tmp += x * s[i][j];
    		}
    	sort(a + 1, a + 10, cmp);
    	dfs(a[1].id, 1, 0, tmp);
    	printf("%d
    ", ans);
    	return 0;
    }
    

    完结撒花 (qwq)

  • 相关阅读:
    iptables命令参数简介
    在linux下开启IP转发的方法
    Linux配置IP路由
    NAT转换
    JS实验案例
    Ubuntu kylin优麒麟root用户与静态网络设置
    非对称加密-RSA
    对称加密-DES
    DM5详解
    Visio的安装教程
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/11753621.html
Copyright © 2011-2022 走看看