Fliptile(USACO 2007 Nov)

来源:互联网 发布:js获取file绝对路径 编辑:程序博客网 时间:2024/06/02 19:25

题目描述

Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in which they manipulate an M × N grid (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) of square tiles, each of which is colored black on one side and white on the other side.

As one would guess, when a single white tile is flipped, it changes to black; when a single black tile is flipped, it changes to white. The cows are rewarded when they flip the tiles so that each tile has the white side face up. However, the cows have rather large hooves and when they try to flip a certain tile, they also flip all the adjacent tiles (tiles that share a full edge with the flipped tile). Since the flips are tiring, the cows want to minimize the number of flips they have to make.

Help the cows determine the minimum number of flips required, and the locations to flip to achieve that minimum. If there are multiple ways to achieve the task with the minimum amount of flips, return the one with the least lexicographical ordering in the output when considered as a string. If the task is impossible, print one line with the word “IMPOSSIBLE”.

输入输出格式

输入格式:

Line 1: Two space-separated integers: M and N

Lines 2..M+1: Line i+1 describes the colors (left to right) of row i of the grid with N space-separated integers which are 1 for black and 0 for white

输出格式:

Lines 1..M: Each line contains N space-separated integers, each specifying how many times to flip that particular location.

输入输出样例

输入样例#1:

4 4
1 0 0 1
0 1 1 0
0 1 1 0
1 0 0 1

输出样例#1:

0 0 0 0
1 0 0 1
1 0 0 1
0 0 0 0

中文翻译(感谢北师大讲义)

农夫约翰知道, 聪明的奶⽜可以产更多的⽜奶。他为奶⽜设
计了⼀种智⼒游戏, 名叫翻转棋。翻转棋可以分成
M  N(1  M; N  15) 个格⼦, 每个格⼦有两种颜⾊, ⼀面
是⿊的, ⼀面是白的。
▶ ⼀旦翻转某个格⼦, 这个格⼦的颜⾊就会颠倒。如果把所有
的格⼦都翻成白的, 就算奶⽜赢了。然⽽, 奶⽜的蹄⼦很⼤,
⼀旦它们打算翻转某个格⼦, 这个格⼦附近(即和这个格⼦
有公共边) 的格⼦也会被翻转。⼀直翻来翻去也很⽆聊, 奶
⽜们想最小化必须翻动的次数。
▶ 请帮助奶⽜确定翻动的最少次数和具体的翻法。如果最小
解有多个, 则输出在字典序意义下最小的那个, 如

/**************************    Name:Fliptile    How to get:USACO    By:Shine_Sky**************************//*******************************    一开始不知道做,看题解说什么确定第一行    就可以确定全部,一直不理解为什么    手动推了一遍发现是这样的    最后只要判断最后一行是不是合法的好了    而且注意方向坐标的i不要冲突(WA了n次)    还有注意输出格式! 要打空格!(WA了1次) *******************************/#include<iostream>#include<cstdio>#define No puts("IMPOSSIBLE")#define f(i,a,b) for(register int i=a;i<=b;i++)#define fd(i,a,b) for(register int i=a;i>=b;i--)using namespace std;inline int read(){    int data=0,w=1; char ch=0;    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();    if(ch=='-') w=-1,ch=getchar();    while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();    return data*w;}inline void write(int x){    if(x<0) putchar('-'),x=-x;    if(x>9) write(x/10);    putchar(x%10+'0');}const int N=15+7;const int fx[5][2]={{-1,0},{1,0},{0,-1},{0,1},{0,0}};int n=read(),m=read(),Map[N][N],ans[N][N],now_ans[N][N],p[N][N],Min=123456789;/*inline void change(int x,int y){    f(i,0,4)        p[x+fx[i][0]][y+fx[i][1]]^=1;}*/inline void dfs(int x){    if(x>m)    {        f(i,1,n)            f(j,1,m)                p[i][j]=Map[i][j];        f(j,1,m)//只有第一行变化了             if(now_ans[1][j])                f(i,0,4)                    p[1+fx[i][0]][j+fx[i][1]]^=1;        f(i,2,n)            f(j,1,m)                if(p[i-1][j])                {                    now_ans[i][j]=1;                    f(k,0,4)                        p[i+fx[k][0]][j+fx[k][1]]^=1;                }                else                    now_ans[i][j]=0;        f(i,1,n)            f(j,1,m)                if(p[i][j])                    return;        int tot=0;        f(i,1,n)            f(j,1,m)                if(now_ans[i][j])   tot++;        if(tot>=Min)    return;        Min=tot;//      printf("RE");        f(i,1,n)            f(j,1,m)                ans[i][j]=now_ans[i][j];        return;    }    f(i,0,1)    {        now_ans[1][x]=i;        dfs(x+1);    }}int main(){    f(i,1,n)        f(j,1,m)            Map[i][j]=read();    dfs(1);    if(Min==123456789)        No;    else        f(i,1,n)        {            f(j,1,m)                write(ans[i][j]),putchar(' ');            puts("");        }    return 0;}
原创粉丝点击