题目描述

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

代码:

#include<bits/stdc++.h>
#define il inline
#define ll long long
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=;
int mp[N][N],dep,tmp[N][N],squ[N],line[N],lit[N];
bool vis[N][N]; il void change(int x,int y){
if(x<=){
if(y<=)squ[]^=;
else if(y<=)squ[]^=;
else squ[]^=;
return;
}
else if(x<=){
if(y<=)squ[]^=;
else if(y<=)squ[]^=;
else squ[]^=;
return;
}
else {
if(y<=)squ[]^=;
else if(y<=)squ[]^=;
else squ[]^=;
return;
}
} il void dfs(int tot,int lsx,int lsy){
if(tot>dep||lsx==)return;
int px=,py=,ps=;
For(i,,) {
if(line[i]&)px++;
if(lit[i]&)py++;
if(squ[i]&)ps++;
}
if((!px)&&(!py)&&(!ps))cout<<tot-,exit();
if(tot+max(px,max(py,ps))>dep)return;
lsy++;
if(lsy>)lsy=,lsx++;
tmp[lsx][lsy]^=,line[lsx]^=,lit[lsy]^=,change(lsx,lsy);
dfs(tot+,lsx,lsy);
tmp[lsx][lsy]^=,line[lsx]^=,lit[lsy]^=,change(lsx,lsy);
dfs(tot,lsx,lsy);
} int main(){
For(i,,) {
For(j,,){
scanf("%1d",&tmp[i][j]);
if(tmp[i][j])line[i]^=,lit[j]^=,change(i,j);
}
}
bool f=;
For(i,,) if((line[i]&)||(lit[i]&)||(squ[i]&)){f=;break;}
if(!f)cout<<;
else while()dep++,dfs(,,);
return ;
}

P3032 [USACO11NOV]二进制数独Binary Sudoku的更多相关文章

  1. [USACO11NOV]二进制数独Binary Sudoku

    传送门 这道题是很好的一道IDA*练习题. 首先我们先确定搜索的框架,我们要求的是用最少的修改次数使得所有的行,列,宫之内都有偶数个1,最直观的想法显然是先预处理出有奇数个1的行,列,宫,之后枚举每一 ...

  2. 2016年11月3日JS脚本简介数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6.布尔型数据:bool 7.对象类型:object 8.二进制:binary 语言类型: 1.强类型语言:c++ c c# java 2.弱类型语

    数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6 ...

  3. MySQL 二进制日志(Binary Log)

    同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分. MySQL有几种不同的日志文件.通常包括错误日志文件,二进制日志,通用日志,慢查询日志,等等.这些日志能够帮助我们定位mysqld ...

  4. [逆向工程] 二进制拆弹Binary Bombs 快乐拆弹 详解

    二进制拆弹 binary bombs 教你最快速解题,成功拆弹 最近计算机基础课,的实验lab2,二进制拆弹,可以说是拆的我很快乐了(sub n, %hair) 此处头发减n 我刚开始做的时候很是懵逼 ...

  5. Leetcode之回溯法专题-37. 解数独(Sudoku Solver)

    Leetcode之回溯法专题-37. 解数独(Sudoku Solver) 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次.数字 1 ...

  6. 二进制日志BINARY LOG清理

    mysql> show master logs; +------------------+-----------+ | Log_name | File_size | +------------- ...

  7. Arduino 串口篇 Arduino发送二进制 send binary via RS232-to-USB to PC

    有用的链接在这里:http://hi.baidu.com/mizuda/item/06b7fdc1d0e45a0ec710b2dd 更加详细的内容请查阅Arduino官方:http://arduino ...

  8. 求解数独难题, Sudoku问题(回溯)

    Introduction : 标准的数独游戏是在一个 9 X 9 的棋盘上填写 1 – 9 这 9 个数字,规则是这样的: 棋盘分成上图所示的 9 个区域(不同颜色做背景标出,每个区域是 3 X 3 ...

  9. [Swift]LeetCode36. 有效的数独 | Valid Sudoku

    Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to th ...

随机推荐

  1. (转)Maven POM中的各种scope的行为总结

    原地址:https://blog.csdn.net/cnweike/article/details/52221410 compile:默认的scope.任何定义在compile scope下的依赖将会 ...

  2. 添加fileinfo扩展

    首先声明:笔者用的是军哥的lnmp一键安装包!链接地址:https://lnmp.org 打开upgrade_php.sh配置文件[文件所在位置:~/lnmp1.4/include/upgrade_p ...

  3. 01javascript基础

    1.JavaScript:直接写入 HTML 输出流 实例:(只能在 HTML 输出中使用 document.write.如果在文档加载后使用该方法,会覆盖整个文档) <!DOCTYPE htm ...

  4. background兼容IE9以下版本

    .box {    width:100%;    height:80%;        background: url('img/nav_bg.png') no-repeat;    backgrou ...

  5. STM32Cube 5.0 使用V1.7.0的固件库生成keil5环境下的F1工程时发现问题

    生成的stm32f1xx_hal_msp.c文件里面,HAL_MspInit(void)函数居然没有了之前1.6库里面的系统中断优先级的设置: /* MemoryManagement_IRQn int ...

  6. stata操作

    //stata操作 *************************数据基本操作****************************** gen varname = value //定义变量 r ...

  7. 分享一个根据具体的日期判断星座的PHP函数

    其实原理很简单,也就是把所有的星座月份日期范围存储到一个数组中,然后根据日期判断属于哪个范围,这样就得到是哪个星座了. 下面的这个函数写的比较精炼,可以参考一下 function constellat ...

  8. C++拷贝构造函数 的理解

    #include <iostream> using namespace std; //拷贝构造函数的理解 class Point { public: Point(); Point(int ...

  9. python学习之函数基础

    第一个python函数: >>> def func_1(): ... print 'hello python' ... >>> func_1() hello pyt ...

  10. java 第六章 面向对象基础

    1.面向对象编程思想 面向过程编程 传统的C语言属于面向过程编程.面向过程解决问题的思路:通常是分析出解决问题所需要的步骤,然后用方法把这些步骤一步一步实现,最后一个一个依次调用方法来解决. 面向过程 ...