题目 :给出N*M大小的字符串矩阵,每个格子有个字符串,求出不同的两行和两列,使得这两行相等.
1 | 2 | 3 |
4 | 5 | 7 |
2 | 5 | 7 |
看表格,就是2行3列和2行3列,确定的这四个元素,上下对应相等.
思路:1.写一个发ID函数,把每个字符串编号.用map来存(因为等会要用这个编号)
int ID(const string &s){
if(!id.count(s)){
id[s]=cnt++;
}
return id[s];
}
2.注意处理分割字符串,使用substr等函数可以展开某个字符串用法看代码.string::pos是一个常数 通常是find找不到就返回这个值。
3.注意扫时候的技巧。观察到列数较少,就先确定两列,扫描行.遇到新的一行,就把对应行列的那两个数存进一个新开的map(这个map在换列的时候要初始化,所以不如在换列上面那个函数声明一下),
因为map自带查重,然后每次count一下新进的那个二元组(用pair存那2数字然后塞进map)是否重复,重复了就代表找到了,退出该函数.
完整代码:(用getline的时候要注意有没有吃到上一行的回车)
#include<bits/stdc++.h>
#define maxr 10000+5
#define maxc 15
using namespace std;
typedef pair<int,int> PII;
map<string,int> id;
int n,m,cnt=0;
int db[maxr][maxc];
int ID(const string &s){
if(!id.count(s)){
id[s]=cnt++;
}
return id[s];
}
void findd(){
for(int c1=0;c1<m-1;c1++){
for(int c2=c1+1;c2<m;c2++){
map<PII,int> d;
for(int i=0;i<n;i++){
PII x=make_pair(db[i][c1],db[i][c2]);
if(!d.count(x)){
d[x]=i;
}
else{
cout<<"NO"<<endl;
cout<<d[x]+1<<' '<<i+1<<endl;
cout<<c1+1<<' '<<c2+1<<endl;
return ;
}
}
}
}
cout<<"YES"<<endl;
}
int main(){ int i,j,k;
while(scanf("%d%d",&n,&m)==2&&n&&m){
getchar();
cnt=0;id.clear();
for(i=0;i<n;i++){
string s;
getline(cin,s);int lastpos=0;
for(j=0;j<m;j++){
int p=s.find(',',lastpos);
if(p==string::npos) p=s.length();
db[i][j]=ID(s.substr(lastpos,p-lastpos));
lastpos=p+1;
}
}
findd();
}
return 0;}