Summer Training #10 Div.2 E(暴力+回溯)

题目链接

题意:给9乘9的数独矩阵,挖去其中5个元素,要求补全其余元素

所犯错误:1.题目中所给的数独矩阵本身可能就是错的(没认真看题,wa惨了)

       2.回溯时,遇到正确的答案就终止循环

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
bool flag[3][11][11];
int n,a[11][11],b[7][5],k,ans[7],f;
bool valid(){
    for(int i=1;i<=9;i++)
    for(int j=1;j<=9;j++){
        for(int z=0;z<3;z++)
        if(flag[z][i][j]==true){return false;}
    }
    return true;
}
void found(int i){
    int j;
    if(i==6){if(valid())f=true;return;}
    for(j=1;(j<=9);j++){
            if((flag[0][b[i][0]][j])&&(flag[1][b[i][1]][j])&&(flag[2][b[i][2]][j])){
                flag[0][b[i][0]][j]=false;
                flag[1][b[i][1]][j]=false;
                flag[2][b[i][2]][j]=false;
                ans[i]=j;
                found(i+1);
                if(f)break;
                flag[0][b[i][0]][j]=true;
                flag[1][b[i][1]][j]=true;
                flag[2][b[i][2]][j]=true;
            }
            }
}
void init(){
    for(int i=1;i<=9;i++){
            for(int z=1;z<=9;z++){
                flag[0][i][a[i][z]]=false;
                flag[1][i][a[z][i]]=false;
                flag[2][i][a[(i-1)/3*3+1+(z-1)/3][(i-1)%3*3+1+(z-1)%3]]=false;

            }
    }
}
int main(){
    scanf("%d",&n);
    char c;
    while(n--){
        k=0;
        f=false;
        memset(flag,true,sizeof(flag));
        for(int i=1;i<=9;i++){
               getchar();
        for(int j=1;j<=9;j++){
            scanf("%c",&c);
            a[i][j]=int(c)-‘0‘;
            if(a[i][j]==0){
                k++;
                b[k][0]=i;
                b[k][1]=j;
                b[k][2]=((i-1)/3)*3+1+(j-1)/3;
            }
        }
        }
        init();
        found(1);
        if(f){
            for(int p=1;p<=5;p++)
            a[b[p][0]][b[p][1]]=ans[p];

            for(int i=1;i<=9;i++){
                for(int j=1;j<=9;j++){
                    printf("%d",a[i][j]);
                }
                printf("\n");
            }
        }
        else printf("Could not complete this grid.\n");
        printf("\n");
    }
    return 0;
}

时间: 2024-08-10 02:51:06

Summer Training #10 Div.2 E(暴力+回溯)的相关文章

Summer Training #10 Div.2 D (最大二分匹配)

题目链接 题意:有许多party在同一天举行,每个party有开始时间与截止时间,爱玩的女主要在一天中参加尽量多的party,而且每个party待的时长不小于半个小时,求女主最多能够参加的party数量. 1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 #define captype __int32 6 const int N = 4005; 7 8

UESTC 2014 Summer Training #10 Div.2

B.Race to 1 UVA 11762 第一次接触概率dp,完全没想到是dp...没想到能递推出来0 0 首先需要知道 总的期望=每件事的期望×每件事发生的概率 然后可以根据这个来写递推公式,也是dp? 假设不小于x的质数有m个,x的质因子有n个(种 更确切),那么在求X的期望时,可以考虑由他能转移过去的状态转移,X,X/pi p是x的质因子 所以不难得出E(x) = 1+(m-n)/mE(X)+1/msigmaE(X/pi) 注意会加1,因为X转移到后面的情况,就多了一步 //Update

UESTC 2014 Summer Training #3 Div.2

(更新中) A:ZOJ 3611 BFS+状态压缩 [题意]:给定一张n*m的图,图上每个点有如下情况:L,R,D,U:代表在该点上只能往它已经给定的方向前进.#,W:不能走到该点.$:走到该点,可以花两分钟得到一分值,然后可以从该点向任意方向走.0:走到该点后可以向任意方向走.然后给你起点和终点坐标,问是否能从起点走到终点,如果能,求出可获得的最大分值以及与之对应达到该最大分值所需的的最小时间花 费.(其中起点和终点坐标可以相同)[知识点]:BFS+状态压缩[题解]:我觉得超级棒的题!真心感觉

UESTC 2014 Summer Training #16 Div.2

虽然被刷了还是要继续战斗下去嗯...就是基础不好,难度相对较大 A.SPOJ AMR10A 点是顺时针给出的,可以在图上画画(脑补也行),连线x-a,x-b(x为选定的一个点,比如第一个点),就把所求面积分成了四部分,a-b左边部分是较容易求出来的, 三角形面积是直接可求,另外两个多边形面积是可以预处理出来的(多个三角形面积和) 反正我是沒想出來...看題解也理解半天,多邊形面積转化为三角形面积和 嗯嗯 #include <iostream> #include <cstdio> #

UESTC 2014 Summer Training #7 Div.2

DAY7一开始状态还行,最高纪录rank7,然后没力气了,一直跌到rank24,问题还是很多呐.昨天总结的问题依然很大. Problem A UVA 12377 就一开始还是慌了,没审清楚题意就去WA了一发. 大意是给你一个数字表示的字符串,最高20位,第一表示有N个质数,后面是其幂的非降序排列,所求能表示的数个数. 简单的排列组合题,不过需要处理出2~END的不同划分,并且满足非降序,用dfs处理即可. 具体就是dfs过程中记录下每一个数字出现的次数,因为相同的次数是不计顺序的,需要在统计时除

UESTC 2014 Summer Training #5 Div.2

持续更新中 B:URAL 1874 三分搜索 [题意]: 给出两条边a,b以及一个墙角,求由这两条边和墙角所构成的四边形的最大面积.[知识点]: 三分搜索[题解]: 将四边形分为两个三角形,其中一个由a,b,以及第三条同时作为墙角斜边的边c,另一个三角形即为墙角与边c构成 则墙角所在的三角形的最大面积为c*c/4,abc变所在的三角形的面积可用海伦公式求出,然后主要是用三分来求这个c,得到c后就可以得到最佳答案了. 还有一种现成的结论...[代码1]: 1 #include <map> 2 #

UESTC 2014 Summer Training #6 Div.2

又是只过两水题,不过状态有些回升,也是差点一血. Problem A SPOJ AMR11A 显然的dp?就一抖就想到尝试从(R,C)推到(1,1),正着推的话,只能检查某一种解可不可行(就有人想出了二分+DP的神奇方法..刚卡过..不过上界是把所有龙加起来..不闲麻烦的话..可以按照贪心的方法先跑一个上界,就每一步选当前最优) 倒着推,龙的话,就加上,药水的话,减去?不够,和1取最大值:某一个点的f[i][j]就是两种策略取最小值: f[i][j] = min{ max(1, f[i+1][j

UESTC 2014 Summer Training #18 Div.2

A.UVALive 6661 题意从1~N中选k个数,和为s的方案数 第一眼搜索,估计错状态量,又去yydp...浪费大量时间 数据很小的,状态数都不会超过2^N...直接dfs就过了 //state二进制表示选取的数 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int maxn = 200; in

Codeforces Round #224 (Div. 2) D 暴力搜索加记忆化

题意读了半年,英语太渣,题意是摆两个棋子在棋盘上作为起点,但是起点不能在#上,然后按照图的指示开始走, < 左 > 右 ^上 v下,走的时候只能按照图的指示走,如果前方是 #的话,可以走进去,但是 走进去之后便不能再走了,走的途中两个棋子不能相碰,但是最终都走到同一个#里是没事的,并且若是能走 无限步的话 输出 -1, 例如  > < 这样左右左右的走就能无限走,然后问你 两个棋子走的最大步数的和 一开始被输出-1给困住了,因为除了 .> <这样以外  还可以刚好形成一