题目链接:https://www.luogu.org/problemnew/show/P5427
题意:
给你一个L和R组成的n*n的矩阵(可以类比为01矩阵),问你能不能找到这样一个位置,先将它翻转之后,对剩下的矩阵翻转任意行或者任意列,可以使得所有的格子都为0或者1
做法:
之前做过一道类似的题目还会更难一点,这里的话用到了bitset优化,以某一行i作为一个标准去异或其他所有行,如果异或行j出来的值val取min(val,n-val),就是将行j变到和行i完全相似或者相反需要变的最少的点数。如果能找到这样一行使得和其他行得到的异或和为1,那么就找到了答案,即只有一行有1的贡献,那么就可以找这个行上的所有列,如果val等于1就去找这两行上的不同值,如果val为n-1就去找这两行相同的值即可。(这样做的话和最小的x和y其实并没有什么关系)
#include<bits/stdc++.h>
using namespace std;
char x[1002];
bitset<1002> B[1002];
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
B[i].reset();
scanf("%s",x+1);
for(int j=1;j<=n;j++){
if(x[j]=='R')B[i].set(j);
}
}
int ansx=-1,ansy=-1,flag=0;
for(int i=1;i<=n;i++){
int sum=0;
for(int j=1;j<=n;j++){
if(i==j)continue;
B[0]=B[i]^B[j];
int sub=B[0].count();
sub=min(sub,n-sub);
sum+=sub;
}
if(sum==1){
for(int j=1;j<=n;j++){
if(i==j)continue;
B[0]=B[i]^B[j];
int sub=B[0].count();
if(sub==1){
for(int k=1;k<=n;k++){
if(B[i][k]!=B[j][k]){
ansx=j,ansy=k;
flag=1;break;
}
}
}
else if(n-sub==1){
for(int k=1;k<=n;k++){
if(B[i][k]==B[j][k]){
ansx=j,ansy=k;
flag=1;break;
}
}
}
if(flag) break;
}
}
}
if(flag==0) printf("-1\n");
else printf("%d %d\n",ansx,ansy);
}