题目
源地址:
http://poj.org/problem?id=2965
理解
参考的某神牛的解法:
证明:
- 要使一个为'+'的符号变为'-',必须其相应的行和列的操作数为奇数;可以证明,如果'+'位置对应的行和列上每一个位置都进行一次操作,则整个图只有这一'+'位置的符号改变,其余都不会改变.
- 设置一个4*4的整型数组,初值为零,用于记录每个点的操作数,那么在每个'+'上的行和列的的位置都加1,得到结果模2(因为一个点进行偶数次操作的效果和没进行操作一样),然后计算整型数组中一的
- 个数即为操作数,'-'的位置为要操作的位置(其他原来操作数为偶数的因为操作并不发生效果,因此不进行操作)
只适用于这一道题,POJ上那道棋盘翻转貌似不能通用。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
bool mark[4][4];
char s[4][4];
int i, j, k;
int ci[16], cj[16];
int nas = 0;
int main(int argc, char const *argv[])
{
memset(mark, 0, sizeof(mark));
for (i = 0; i < 4; i++)
cin >> s[i];
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
char c = s[i][j];
if (c == '+')
{
mark[i][j] = !mark[i][j];
for (k = 0; k < 4; k++)
{
mark[i][k] = !mark[i][k];
mark[k][j] = !mark[k][j];
}
}
}
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
if (mark[i][j] == true)
{
ci[nas] = i + 1;
cj[nas] = j + 1;
nas ++;
}
printf("%d\n", nas);
for (i = 0; i < nas; i++)
{
printf("%d %d\n", ci[i], cj[i]);
}
return 0;
}
更新日志
- 2014年07月23日 已AC。