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

    代码:

    #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=15;
    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<=3){
            if(y<=3)squ[1]^=1;
            else if(y<=6)squ[2]^=1;
            else squ[3]^=1;
            return;
        }
        else if(x<=6){
            if(y<=3)squ[4]^=1;
            else if(y<=6)squ[5]^=1;
            else squ[6]^=1;
            return;
        }
        else {
            if(y<=3)squ[7]^=1;
            else if(y<=6)squ[8]^=1;
            else squ[9]^=1;
            return;
        }
    }
    
    il void dfs(int tot,int lsx,int lsy){
        if(tot>dep||lsx==10)return;
        int px=0,py=0,ps=0;
        For(i,1,9) {
            if(line[i]&1)px++;
            if(lit[i]&1)py++;
            if(squ[i]&1)ps++;
        }
        if((!px)&&(!py)&&(!ps))cout<<tot-1,exit(0);
        if(tot+max(px,max(py,ps))>dep)return;
        lsy++;
        if(lsy>9)lsy=1,lsx++;
        tmp[lsx][lsy]^=1,line[lsx]^=1,lit[lsy]^=1,change(lsx,lsy);
        dfs(tot+1,lsx,lsy);
        tmp[lsx][lsy]^=1,line[lsx]^=1,lit[lsy]^=1,change(lsx,lsy);
        dfs(tot,lsx,lsy);
    }
    
    int main(){
        For(i,1,9) {
            For(j,1,9){
                 scanf("%1d",&tmp[i][j]);
                 if(tmp[i][j])line[i]^=1,lit[j]^=1,change(i,j);
             }
        }
        bool f=0;
        For(i,1,9) if((line[i]&1)||(lit[i]&1)||(squ[i]&1)){f=1;break;}
        if(!f)cout<<0;
        else while(1)dep++,dfs(1,1,0);
        return 0;
    }
  • 相关阅读:
    Ajax核心对象和AjaxPro框架
    ASP.NET XML与JSON
    jQuery中Ajax的应用
    jQuery中操作表单与表格
    IOS 非常流畅的滑动tableView
    提高自己应用性能的总结架构篇
    LazyCode 自己开源的一个类库
    iOS 自己写的对话框中加入三个输入框
    icmp 流量抓取 转发 代理(2)
    sublime text ctags插件使用
  • 原文地址:https://www.cnblogs.com/five20/p/9298883.html
Copyright © 2011-2022 走看看