Lamps 【题目描述】 有一个 $n \times m$ 的灯具,每个格子里都有一盏小灯。每一列格子的下方都有一个开关,可以控制整列格子的灯的状态变化。就是说按一下这个开关,那么这列上的灯的状态都会改变。如果某一行的所有灯的状态都是开着的,那么这一行就称为是「Light」的。 给你这个灯具的初始状态,你需要精确地按次开关。求最多有几行是「Light」的。 【输入格式】 第一行三个正整数 $N,M$ 和 $K$,满足 $1 \leq n,m \leq 100$,$0 \leq k \leq 1000$。 接下来 $N$ 行,每行一个长度为 $M$ 的 $01$ 字符串,$1$ 表示这盏灯是开着的,$0$ 表示这盏灯是关着的。 【输出格式】 输出仅包含一个整数,为最多的的行数。 【样例输入】 ``` 3 2 1 01 10 10 ``` 【样例输出】 ``` 2 ```

经过分析,发现没有必要对于同一列操作两次以上,这样会回到原先的情况(除非是消磨步数),所以每一种可能性,让被枚举的那行成为「Light」。
发现一行成为「Light」之后这种情况就被固定了下来,多余的次数用来消磨掉,如果多余次数正好是奇数,只能遗憾无解。
显然步数不够的时候也只能无解。
处理使一行「Light」时,要是另一行与这行一模一样,这行一定也会成为「Light」行,那么可能最大方案数 +1。
最后把方案数进行比较输出最大值就行了。

#include<iostream>
#include<cstdio>
#include<string>//头文件
using namespace std;
char a[101][101];//储存开关情况
int sum[101];//记录每行需要打开的次数
int main()
{
	std::ios::sync_with_stdio(false);//关闭同步,加速
	int i,j,k;
	int _i,_j,_k;
	int flag,ans,maxn=-1;//-1角逐出最大值
	int T,t,n,m;
	
	cin>>n>>m>>k;
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			cin>>a[i][j];
			if(a[i][j]=='0')
			{
				sum[i]++;//记录每行操作数
			}
		}
	}
	for(i=1;i<=n;i++)
	{
		_k=k-sum[i];//用_k记录剩余步数
		if(_k<0)continue;//步数不够
		if(_k&1)continue;//剩余奇数次,位运算加速,相当于if(k%2==1)
		ans=1;//初始化
		for(_i=1;_i<=n;_i++)
		{
			if(_i==i)continue;//防止自己和自己比较
			flag=1;
			for(_j=1;_j<=m;_j++)
			{
				if(a[_i][_j]!=a[i][_j])
				{
					flag=0;
					break;
				}
			}
			if(flag==1)ans++;//如果一模一样,可能次数增加
		}
		maxn=max(maxn,ans);//比较最大值
	}
	cout<<maxn;
	
	return 0;
}