hihocoder 第五十二周 高斯消元·二【高斯消元解异或方程 难点【模板】】

题目地址:http://hihocoder.com/contest/hiho57/problem/1

输入

第1..5行:1个长度为6的字符串,表示该行的格子状态,1表示该格子是亮着的,0表示该格子是暗的。

保证一定存在解,且一定存在暗着的格子。

输出

需要按下的格子数量k,表示按下这k个位置后就可以将整个游戏板所有的格子都点亮。

接下来k行,每行一个坐标(x,y),表示需要按下格子(x,y)。x坐标较小的先输出,若x相同,则先输出y坐标较小的。

样例输入
001111
011111
111111
111110
111100
样例输出
2
1 1
5 6
分析:这个是一道高斯消元解异或方程的问题,样例输入要当成字符串读入。我用的模板算法是将所有的1翻成0.
所以在做这道题目时,我读入样例输入矩阵时,将0替换成1存储,将1替换成0存储。
代码:
 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <cmath>
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#define N 100000+100 using namespace std; int a[][]; //0 1矩阵
int x[]; void gauss()
{
int i, j, k;
for(k=; k<; k++)//表示列
{
i=k;
for(i; i<; i++)
if(a[i][k]!= )//当前位置不等于0
break;
for(j=; j<=; j++)
swap(a[k][j], a[i][j] );
for(i=; i<; i++){
if(k!=i && a[i][k] ){
for(j=; j<=; j++)
a[i][j]=a[k][j]^a[i][j];
}
}
}
for(i=; i<; i++)
x[i]=a[i][];
} int main()
{
int i, j, k;
memset(a, , sizeof(a));
memset(x, , sizeof(x));
char s[];
int e=;
for(i=; i<; i++){
scanf("%s", s);
for(j=; j<; j++)
if(s[j]=='') a[e++][]=;
else a[e++][]=;
} /* 这是按照数字读入的方式
for(i=0; i<30; i++){
scanf("%d", &a[i][30]);
x[i]=0; //为什么放在30的位置上
} */ for(i=; i<; i++){
a[i][i]=; //
if( i%!= ) //判断是不是矩阵的最左边
a[i-][i]=;//左标记
if( i%!= ) //判断是不是矩阵的最右边
a[i+][i]=;//右标记
if(i>) //判断是不是第一行
a[i-][i]=;//上标记
if(i<) //判断是不是最后一行
a[i+][i]=;//下标记
}//影响矩阵生成完毕 gauss();
int cnt=;
for(i=; i<; i++)
if(x[i]==) cnt++;
printf("%d\n",cnt );
for (i=; i<; i++)
if(x[i]== ){
printf("%d %d\n", (i/)+, (i%)+ );
} return ;
}

上一篇:[HIHO1196]高斯消元·二(高斯消元、枚举*变元)


下一篇:GitHub 托管的10款免费开源 windows 工具