• [LuoguP1074]靶形数独_搜索


    靶形数独

    题目链接https://www.luogu.org/problem/P1074

    数据范围:略。


    题解

    传说中的大爆搜题啊。

    我觉得这种题就是你能想到什么优化就直接上什么优化....

    这个题我们就贪心的选行,就是按照每行$0$的个数从小到大排序依次填。

    然后我们填的时候需要记录:当前要填的数,在行、列、九宫格里是否出现过即可。

    还有,分数是$5sim 10$,不是$1$到$5$.....

    代码

    #include <bits/stdc++.h>
    
    #define N 110 
    
    using namespace std;
    
    char *p1, *p2, buf[100000];
    
    #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )
    
    int rd() {
    	int x = 0, f = 1;
    	char c = nc();
    	while (c < 48) {
    		if (c == '-')
    			f = -1;
    		c = nc();
    	}
    	while (c > 47) {
    		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
    	}
    	return x * f;
    }
    
    struct Node {
    	int x, y;
    };
    
    inline bool cmp(const Node &a, const Node &b) {
    	return a.y < b.y;
    }
    
    const int n = 9;
    
    inline int id(Node a) {
    	return n * (a.x - 1) + a.y;
    }
    
    inline int id(int x, int y) {
    	return n * (x - 1) + y;
    }
    
    inline Node rz(int x) {
    	return (Node) {(x - 1) / n + 1, (x - 1) % n + 1};
    }
    
    inline int bid(int al) {
    	int x = rz(al).x, y = rz(al).y;
    	x = (x - 1) / 3 + 1, y = (y - 1) / 3 + 1;
    	return (x - 1) * 3 + y;
    }
    
    int Map[N], q[N], Score[N], ans = 0, fil[N];
    
    bool vis[3][10][10];
    
    Node b[11];
    
    void dfs(int k) {
    	if (k == 82) {
    		// puts("??");
    		int sum = 0;
    		for (int i = 1; i <= n; i ++ ) {
    			for (int j = 1; j <= n; j ++ ) {
    				sum += fil[id(i, j)] * Score[id(i, j)];
    			}
    		}
    
    		// for (int i = 1; i <= n; i ++ ) {
    		// 	for (int j = 1; j <= n; j ++ ) {
    		// 		printf("%d ", fil[id(i, j)]);
    		// 	}
    		// 	puts("");
    		// }
    		// puts("");
    		ans = max(ans, sum);
    		return;
    	}
    
    	int x = rz(q[k]).x, y = rz(q[k]).y;
    	// printf("%d %d
    ", x, y);
    	if (!Map[id(x, y)]) {
    		for (int i = 1; i <= 9; i ++ ) {
    			// x, y, i
    			if (!vis[0][x][i] && !vis[1][y][i] && !vis[2][bid(id(x, y))][i]) {
    				vis[0][x][i] = vis[1][y][i] = vis[2][bid(id(x, y))][i] = true;
    				fil[id(x, y)] = i;
    				dfs(k + 1);
    				vis[0][x][i] = vis[1][y][i] = vis[2][bid(id(x, y))][i] = false;
    				fil[id(x, y)] = 0;
    			}
    		}
    	}
    	else {
    		dfs(k + 1);
    	}
    }
    
    int main() {
    	for (int i = 1; i <= 9; i ++ ) {
    		for (int j = 1; j <= 9; j ++ ) {
    			Map[id(i, j)] = rd();
    		}
    	}
    
    	for (int i = 1; i <= 9; i ++ ) {
    		b[i].x = i;
    		for (int j = 1; j <= 9; j ++ ) {
    			int v = Map[id(i, j)];
    			if (!v)
    				b[i].y ++ ;
    			else {
    				vis[0][i][v] = vis[1][j][v] = vis[2][bid(id(i, j))][v] = true;
    				fil[id(i, j)] = v;
    			}
    		}
    	}
    
    	sort(b + 1, b + n + 1, cmp);
    	for (int i = 1; i <= n; i ++ ) {
    		for (int j = 1; j <= n; j ++ ) {
    			int x = b[i].x, y = j;
    			q[id(i, j)] = id(x, y);
    		}
    	}
    
    	// init_score
    	for (int i = 1; i <= n; i ++ ) {
    		for (int j = 1; j <= n; j ++ ) {
    			Score[id(i, j)] = 5;
    		}
    	}
    
    	for (int i = 1; i <= 5; i ++ ) {
    		int x = i, y = n - i + 1;
    		for (int l = x; l <= y; l ++ ) {
    			for (int r = x; r <= y; r ++ ) {
    				Score[id(l, r)] ++ ;
    			}
    		}
    	}
    
    	// for (int i = 1; i <= n; i ++ ) {
    	// 	for (int j = 1; j <= n; j ++ ) {
    	// 		printf("%d ", Score[id(i, j)]);
    	// 	}
    	// 	puts("");
    	// }
    
    	dfs(1);
    
    	if (!ans) {
    		puts("-1");
    	}
    	else {
    		cout << ans << endl ;
    	}
    	return 0;
    }
    
  • 相关阅读:
    koa2 中间件里面的next到底是什么
    nodejs 之 nvm和pm2
    javascript瀑布流
    转使用chrome命令行:disable
    MariaDB 用户与授权
    MariaDB TRANSACTION
    IHS .kdb转crt,key
    MariaDB TRIGGER
    MariaDB CURSOR
    MariaDB PROCEDURE
  • 原文地址:https://www.cnblogs.com/ShuraK/p/11732929.html
Copyright © 2020-2023  润新知