<div class="ptt" style="text-align:center; font-size:18pt; font-weight:bold; color:blue" lang="en-US">The Pilots Brothers' refrigerator</div><div class="plm" style="text-align:center; font-size:14px"><table align="center"><tbody><tr><td><strong>Time Limit:</strong> 1000MS</td><td width="10px"> </td><td colspan="3"><strong>Memory Limit:</strong> 65536K</td></tr><tr><td><strong>Total Submissions:</strong> 19011</td><td width="10px"> </td><td><strong>Accepted:</strong> 7277</td><td width="10px"> </td><td style="font-weight:bold; color:red">Special Judge</td></tr></tbody></table></div><p class="pst" style="font-size:18pt; font-weight:bold; color:blue">Description</p><div class="ptx" style="font-family:'Times New Roman',Times,serif; font-size:14px" lang="en-US"><span lang="en-us"></span><p>The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator.</p><p>There are 16 handles on the refrigerator door. Every handle can be in one of two states: open or closed. The refrigerator is open only when all handles are open. The handles are represented as a matrix 4х4. You can change the state of a handle in any location <strong>[i, j]</strong> (1 ≤ i, j ≤ 4). However, this also changes states of all handles in row <strong>i</strong> and all handles in column <strong>j</strong>.</p><p>The task is to determine the minimum number of handle switching necessary to open the refrigerator.</p></div><p class="pst" style="font-size:18pt; font-weight:bold; color:blue">Input</p><div class="ptx" style="font-family:'Times New Roman',Times,serif; font-size:14px" lang="en-US"><span lang="en-us"></span><p>The input contains four lines. Each of the four lines contains four characters describing the initial state of appropriate handles. A symbol “+” means that the handle is in closed state, whereas the symbol “−” means “open”. At least one of the handles is initially closed.</p></div><p class="pst" style="font-size:18pt; font-weight:bold; color:blue">Output</p><div class="ptx" style="font-family:'Times New Roman',Times,serif; font-size:14px" lang="en-US"><span lang="en-us"></span><p>The first line of the input contains N – the minimum number of switching. The rest N lines describe switching sequence. Each of the lines contains a row number and a column number of the matrix separated by one or more spaces. If there are several solutions, you may give any one of them.</p></div><p class="pst" style="font-size:18pt; font-weight:bold; color:blue">Sample Input</p><pre name="code" class="sio" style="font-family:'Courier New',Courier,monospace; font-size:14px">-+--
----
----
-+--
Sample Output
6 1 1 1 3 1 4 4 1 4 3 4 4/*
参考高手的高效解法:
> 证明:要使一个为'+'的符号变为'-',必须其相应的行和列的操作数为奇数;可以证明,如果'+'位置对应的行和列上每一个位置都进行一次操作,则整个图只有这一'+'位置的符号改变,其余都不会改变.
> 设置一个4*4的整型数组,初值为零,用于记录每个点的操作数,那么在每个'+'上的行和列的的位置都加1,得到结果模2(因为一个点进行偶数次操作的效果和没进行操作一样,这就是楼上说的取反的原理),然后计算整型数组中一的
> 个数即为操作数,一的位置为要操作的位置(其他原来操作数为偶数的因为操作并不发生效果,因此不进行操作)
*********************************
此上证其可以按以上步骤使数组中值都为‘-’
********************************
在上述证明中将所有的行和列的位置都加1后,在将其模2之前,对给定的数组状态,将所有的位置操作其所存的操作数个次数,举例,如果a[i][j]==n,则对(i,j)操作n次,当所有的操作完后,即全为‘-’的数组。
其实就是不模2的操作,作了许多的无用功。
以上的操作次序对结果无影响,如果存在一个最小的步骤,则此步骤一定在以上操作之中。(简单说下:因为以上操作已经包含了所有可改变欲改变位置的操作了)
而模2后的操作是去掉了所有无用功之后的操作,此操作同样包含最小步骤。
但模2后的操作去掉任何一个或几个步骤后,都不可能再得到全为‘-’的。(此同样可证明:因为操作次序无影响,先进行最小步骤,得到全为‘-’,如果还剩下m步,则在全为‘-’的数组状态下进行这m步操作后还得到一个全为
‘-’的数组状态,此只能是在同一个位置进行偶数次操作,与前文模2后矛盾,所以m=0),因此模2后的操作即为最小步骤的操作。
*/
#include<iostream>#include<string.h>#include<stdio.h>using namespace std;bool book[4][4];char s[4][4];int main(){ int i,j,k; char c; for( i=0;i<4;i++) cin>>s[i]; memset(book,0,sizeof(book)); for(i=0;i<4;i++) for(j=0;j<4;j++) { char c; c=s[i][j]; if(c=='+') { book[i][j]= !book[i][j]; for( k=0;k<4;k++) { book[i][k] = !book[i][k]; book[k][j]=!book[k][j]; } } } int xx[20]; int yy[20]; int ans =0,count =0; for(i=0;i<4;i++) for(j=0;j<4;j++) { if(book[i][j]) { ans++; xx[count]=i+1; yy[count]=j+1; count ++; } } printf("%d\n",ans); for(i=0;i<count;i++) printf("%d %d\n",xx[i],yy[i]);}