P3032 [USACO11NOV]二进制数独Binary Sudoku

题目描述

Farmer John's cows like to play an interesting variant of the popular game of "Sudoku". Their version involves a 9 x 9 grid of 3 x 3 subgrids, just like regular Sudoku. The cows' version, however, uses only binary digits:

000 000 000

001 000 100

000 000 000

000 110 000

000 111 000

000 000 000

000 000 000

000 000 000

000 000 000

The goal of binary Sudoku is to toggle as few bits as possible so that each of the nine rows, each of the nine columns, and each of the nine 3 x 3 subgrids has even parity (i.e., contains an even number of 1s). For the example above, a set of 3 toggles gives a valid solution:

000 000 000

001 000 100

001 000 100

000 110 000

000 110 000

000 000 000

000 000 000

000 000 000

000 000 000

Given the initial state of a binary Sudoku board, please help the cows determine the minimum number of toggles required to solve it.

给出一个9*9的01矩阵,问最少修改几个数能使每行、每列以及每个九宫格中1的个数均为偶数。

输入输出格式

输入格式:

 

* Lines 1..9: Each line contains a 9-digit binary string corresponding to one row of the initial game board.

 

输出格式:

 

* Line 1: The minimum number of toggles required to make every row, column, and subgrid have even parity.

 

输入输出样例

输入样例#1: 
000000000 
001000100 
000000000 
000110000 
000111000 
000000000 
000000000 
000000000 
000000000 
输出样例#1: 
3 

说明

The Sudoku board in the sample input is the same as in the problem text above.

Three toggles suffice to solve the puzzle.

Solution:

  本题贼有意思。

  很容易想到整个棋盘最多只要$81$次翻转(即把每个棋子都翻转),但是显然实际上不用这么多次。

  那么我们直接$IDA*$,每个位置的棋子要么翻转要么不翻转,然后分别记录一下每行、每列、每个九宫格内的棋子个数,估价函数就是取三者中不满足偶数条件个数最多的个数(至少需要这么多次翻转才能使棋子变为偶数),然后剪枝就好了。

代码:

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
 5 #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
 6 using namespace std;
 7 const int N=15;
 8 int mp[N][N],dep,tmp[N][N],squ[N],line[N],lit[N];
 9 bool vis[N][N];
10 
11 il void change(int x,int y){
12     if(x<=3){
13         if(y<=3)squ[1]^=1;
14         else if(y<=6)squ[2]^=1;
15         else squ[3]^=1;
16         return;
17     }
18     else if(x<=6){
19         if(y<=3)squ[4]^=1;
20         else if(y<=6)squ[5]^=1;
21         else squ[6]^=1;
22         return;
23     }
24     else {
25         if(y<=3)squ[7]^=1;
26         else if(y<=6)squ[8]^=1;
27         else squ[9]^=1;
28         return;
29     }
30 }
31 
32 il void dfs(int tot,int lsx,int lsy){
33     if(tot>dep||lsx==10)return;
34     int px=0,py=0,ps=0;
35     For(i,1,9) {
36         if(line[i]&1)px++;
37         if(lit[i]&1)py++;
38         if(squ[i]&1)ps++;
39     }
40     if((!px)&&(!py)&&(!ps))cout<<tot-1,exit(0);
41     if(tot+max(px,max(py,ps))>dep)return;
42     lsy++;
43     if(lsy>9)lsy=1,lsx++;
44     tmp[lsx][lsy]^=1,line[lsx]^=1,lit[lsy]^=1,change(lsx,lsy);
45     dfs(tot+1,lsx,lsy);
46     tmp[lsx][lsy]^=1,line[lsx]^=1,lit[lsy]^=1,change(lsx,lsy);
47     dfs(tot,lsx,lsy);
48 }
49 
50 int main(){
51     For(i,1,9) {
52         For(j,1,9){
53              scanf("%1d",&tmp[i][j]);
54              if(tmp[i][j])line[i]^=1,lit[j]^=1,change(i,j);
55          }
56     }
57     bool f=0;
58     For(i,1,9) if((line[i]&1)||(lit[i]&1)||(squ[i]&1)){f=1;break;}
59     if(!f)cout<<0;
60     else while(1)dep++,dfs(1,1,0);
61     return 0;
62 }

猜你喜欢

转载自www.cnblogs.com/five20/p/9298883.html