zoukankan      html  css  js  c++  java
  • 洛谷 P1074 靶形数独/LOJ #2591. 「NOIP2009」靶形数独

    洛谷 P1074 靶形数独/LOJ #2591. 「NOIP2009」靶形数独

    loj

    洛谷

    思路

    特别想说一下这道题,因为真的特!别!好!玩!

    数独是啥?

    数独都懂吧

    (1.)每一行不能有一样的数字
    (2.)每一列不能有一样的数字
    (3.)每个(3*3)的九宫格不能有一样的数字

    填出来你就赢了(好牛!!)

    how to do

    首先上来的感觉就是要搜索,那么,搜索的话,我们要想一下怎么搜,这里可以直接记录某一行某个数是否出现,某一列某个数是否出现,某个九宫格内某个数是否出现,前两个好弄,直接循环的时候记录就好了,最后一个怎么办?

    而且怎么计算格子的分数呢??一个一个乘?

    所以,我们要解决的问题是:怎么计算格子的分数,怎么判断是第几个九宫格

    1. 一开始在想怎么计算这个格子的分数是多少,后来决定干脆直接开个(score)数组存下来得了,算的时候一乘就完事儿了
    const int score[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}, };
    
    1. 我的方法是,硬判断,就像下面这样(为了美观一些不需要判断的条件我都打上了,反正影响也不大)
    int pd(int i, int j) {
    	if(i <= 3 && j <= 3) return 1;
    	if(i <= 3 && j <= 6) return 2;
    	if(i <= 3 && j <= 9) return 3;
    	if(i <= 6 && j <= 3) return 4;
    	if(i <= 6 && j <= 6) return 5;
    	if(i <= 6 && j <= 9) return 6;
    	if(i <= 9 && j <= 3) return 7;
    	if(i <= 9 && j <= 6) return 8;
    	if(i <= 9 && j <= 9) return 9;
    }
    

    然后我们就可以一行一行的搜索,填完一行再填下一行,然后就可以得到六十分的好成绩

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int A = 5e5 + 11;
    const int B = 1e6 + 11;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    
    inline int read() {
    	char c = getchar();
    	int x = 0, f = 1;
    	for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    	return x * f;
    }
    
    const int score[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}, };
    
    int pd(int i, int j) {
    	if(i <= 3 && j <= 3) return 1;
    	if(i <= 3 && j <= 6) return 2;
    	if(i <= 3 && j <= 9) return 3;
    	if(i <= 6 && j <= 3) return 4;
    	if(i <= 6 && j <= 6) return 5;
    	if(i <= 6 && j <= 9) return 6;
    	if(i <= 9 && j <= 3) return 7;
    	if(i <= 9 && j <= 6) return 8;
    	if(i <= 9 && j <= 9) return 9;
    }
    
    int a[11][11], hang[11][11], lie[11][11], sma[11][11];
    int tot, ans = -10000;
    
    void coun() {
    	int now = 0;
    	for(int i = 1; i <= 9; i++) 
    		for(int j = 1; j <= 9; j++)
    			now += a[i][j] * score[i][j];
    	ans = max(ans, now);
    	return;
    }
    
    void dfs(int ho, int li) { //行、列、这一行填了多少个 
    	if(ho == 10) { coun(); return; }
    	if(li == 10) dfs(ho + 1, 1);
    	if(!a[ho][li]) {
    		for(int i = 1; i <= 9; i++) {
    			if(!hang[ho][i] && !lie[li][i] && !sma[pd(ho, li)][i]) {
    				hang[ho][i] = lie[li][i] = sma[pd(ho, li)][i] = 1;
    				a[ho][li] = i; dfs(ho, li + 1); a[ho][li] = 0;
    				hang[ho][i] = lie[li][i] = sma[pd(ho, li)][i] = 0;
    			}
    		}
    	}
    	else dfs(ho, li + 1);
    }
    
    int main() {
    	for(int i = 1; i <= 9; i++)
    		for(int j = 1; j <= 9; j++) {
    			a[i][j] = read();
    			if(a[i][j]) {
    				sma[pd(i, j)][a[i][j]] = 1;
    				hang[i][a[i][j]] = 1;
    				lie[j][a[i][j]] = 1;
    			}
    			else tot++;
    		}
    	dfs(1, 1);
    	cout << ans << "
    ";
    	return 0;
    }
    

    怎么优化?

    我不会优化呀!!怎么办!只能搜了……只见大佬说

    从填数最多的一行开始填,这样要选择的数就少了,不合法的情况就可以省掉一些

    然后就满分了(qwq)

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int A = 5e5 + 11;
    const int B = 1e6 + 11;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    
    inline int read() {
    	char c = getchar();
    	int x = 0, f = 1;
    	for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    	return x * f;
    }
    
    const int score[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}, };
    
    int pd(int i, int j) {
    	if(i <= 3 && j <= 3) return 1;
    	if(i <= 3 && j <= 6) return 2;
    	if(i <= 3 && j <= 9) return 3;
    	if(i <= 6 && j <= 3) return 4;
    	if(i <= 6 && j <= 6) return 5;
    	if(i <= 6 && j <= 9) return 6;
    	if(i <= 9 && j <= 3) return 7;
    	if(i <= 9 && j <= 6) return 8;
    	if(i <= 9 && j <= 9) return 9;
    }
    
    int a[11][11], hang[11][11], lie[11][11], sma[11][11];
    int tot, ans = -1;
    struct node { int sum, line; } qwq[11];
    
    bool cmp(node a, node b) {
    	return a.sum < b.sum;
    }
    
    void coun() {
    	int now = 0;
    	for(int i = 1; i <= 9; i++) 
    		for(int j = 1; j <= 9; j++)
    			now += a[i][j] * score[i][j];
    	ans = max(ans, now);
    	return;
    }
    
    void dfs(int cnt, int ho, int li) { //行、列、这一行填了多少个 
    	if(cnt == 10) { coun(); return; }
    	if(li == 10) dfs(cnt + 1, qwq[cnt + 1].line, 1);
    	if(!a[ho][li]) {
    		for(int i = 1; i <= 9; i++) {
    			if(!hang[ho][i] && !lie[li][i] && !sma[pd(ho, li)][i]) {
    				hang[ho][i] = lie[li][i] = sma[pd(ho, li)][i] = 1;
    				a[ho][li] = i; dfs(cnt, ho, li + 1); a[ho][li] = 0;
    				hang[ho][i] = lie[li][i] = sma[pd(ho, li)][i] = 0;
    			}
    		}
    	}
    	else dfs(cnt, ho, li + 1);
    }
    
    int main() {
    	for(int i = 1; i <= 9; i++) {
    		tot = 0;
    		for(int j = 1; j <= 9; j++) {
    			a[i][j] = read();
    			if(a[i][j]) {
    				sma[pd(i, j)][a[i][j]] = 1;
    				hang[i][a[i][j]] = 1;
    				lie[j][a[i][j]] = 1;
    			}
    			else tot++;
    			qwq[i].line = i, qwq[i].sum = tot;
    		}
    	}
    	sort(qwq + 1, qwq + 1 + 9, cmp);
    	dfs(1, qwq[1].line, 1);
    	cout << ans; return 0;
    }
    

    是的你赢了

  • 相关阅读:
    CSS中position小解
    position
    mac默认安装postgresql, 如何让postgresql可以远程访问
    The data directory was initialized by PostgreSQL version 9.6, which is not compatible with this version 10.0.
    active admin gem error
    psql 无法添加超级用户
    ubuntu 15.04 安装Balsamiq Mockups 3
    Rails html 写public里图片的路径
    rails c 历史命令
    undefined local variable or method `per' for []:ActiveRecord::Relation
  • 原文地址:https://www.cnblogs.com/loceaner/p/12103359.html
Copyright © 2011-2022 走看看