题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3780
个人解题思路:
1:逆向自然求解:找到全’X'行 或 全'O'列 删除(对应行/列元素全置0);
2:在任意时刻,不会存在 某行全为‘X' 的同时另外一列全为’O’;反证法:
假设存在并且 全‘X’行的行号为i、 全‘O'列的列号为j ,则在矩阵中坐标为(i,j)的点由于还未被置0,所以其将即为‘X',又为'O',显然不可能。
综上,结论得证。
明白这一点,在循环中先处理 行 或 列 就都可以了,因为同一时刻二者只能有其一成立。
3:可能存在 多行同时为’X‘ 或多列同时为'O",根据题目要求要字典序最小,所以从后往前找时应优先处理 编号 大的行/列。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<list>
#include<stack>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
char matrix[500+5][500+5];
stack<string> stack_operation;
bool flag_row[500+5], flag_column[500+5];
int cnt_row=0,cnt_column=0;
int main(){
#ifndef ONLINE_JUDGE
freopen("testCase.txt","r",stdin);
#endif
int T;
int N;
scanf("%d",&T);
while(T--){
int counter=0;
char str[5];
memset(matrix,0,sizeof(matrix));
memset(flag_row,0,sizeof(flag_row));
memset(flag_column,0,sizeof(flag_column));
scanf("%d",&N);
for(int i=0;i<N;i++)
scanf("%s",matrix[i]);
counter = 2* N;
/* 这里处理时 找全'X'行 或 找全'O'列 不用区分先后,
* 因为当前矩阵 有全'X'行 与 有全'O'列 是互斥的,二者某时刻只能有一成立
*/
while(counter--){
if(cnt_row==N || cnt_column==N)
break;
for(int i=N-1;i>=0;i--){ //行
if(flag_row[i]==true)//已处理过
continue;
for(int j=0;j<N;j++){//列
if(matrix[i][j]!='X'&&matrix[i][j]!=0)
break;
if(j==(N-1)){ //
for(int k=0;k<N;k++)
matrix[i][k] = 0;
flag_row[i] = true;
cnt_row++;
//itoa(i+1,str,10);
sprintf(str,"%d",i+1);
stack_operation.push("R"+string(str));
}
}
}
if(cnt_row==N || cnt_column==N)
break;
for(int i=N-1;i>=0;i--){//列
if(flag_column[i]==true)//已处理过
continue;
for(int j=0;j<N;j++){//行
if(matrix[j][i]!='O'&&matrix[j][i]!=0)
break;
if(j==(N-1)){
for(int k=0;k<N;k++) //行
matrix[k][i] = 0;
flag_column[i] = true;
cnt_column++;
//itoa(i+1,str,10);
sprintf(str,"%d",i+1);
stack_operation.push("C"+string(str));
}
}
}
}
if(stack_operation.size()==0)
cout<<"No solution"<<endl;
else{
while(stack_operation.size()){
cout<<stack_operation.top();
stack_operation.pop();
if(stack_operation.size()!=0)
cout<<' ';
else
cout<<endl;
}
//cout<<endl;
}
}
return 0;
}
测试用例如下:
4
2
XX
OX
2
XO
OX
3
XOX
XOX
XOX
3
OOO
XOO
XXO
对应输出为:
R2 C1 R1
No solution
C1 C3 R1 R2 R3 C2
R1 C1 R2 C2 R3 C3