题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4467
大衣就是给你一个字符串组成的二位数组,让你找到两组一样的数据,即(r1,c1)==(r1,c2)&&(r2,c1)==(r2,c2);
题目并不难,但是直接对字符串进行查找会大大影响效率,所以,我们应该用map把字符串映射成一个整数,这样就会大大的提高效率。
暴力部分是4000ms过的,利用map进行了优化快速查找效率大大提升
#include<bits/stdc++.h>
using namespace std;
string str;
int ii=0;///表示字符串对应的整数
map<string,int> mmp;///构建映射
int main() {
freopen("1.in","r",stdin);
int m,n;
mmp.clear();
while(cin>>m>>n) {
///读入字符串并转换为整型
getchar();
int mp[m][n]= {};
for(int i=0; i<m; i++) {
int r=0;
getline(cin,str);
int leng = str.length();
char lis[1000];
int k=0;
for(int j=0; j<leng; k++,j++) {
if (str[j]!=',') {
lis[k]=str[j];
} else {
lis[k]='\0';
k=-1;
if(mmp.count(lis)) {
mp[i][r]=mmp[lis];
} else {
mp[i][r]=++ii;
mmp.insert(pair<string,int>(lis,ii));
}
r++;
memset(lis,0,sizeof(lis));
}
}
lis[k]='\0';
if(mmp.count(lis)) {
mp[i][r]=mmp[lis];
r++;
} else {
mp[i][r]=++ii;
r++;
mmp.insert(pair<string,int>(lis,ii));
}
memset(lis,0,sizeof(lis));
}
// for(int i=0; i<m; i++) {
// for(int j=0; j<n; j++) {
// cout<<mp[i][j]<<" ";
// }
// cout<<endl;
///几乎是暴力遍历
// for(int i=0; i<n; i++) {
// for(int j=0; j<m; j++) {
// for(int k=j+1; k<m; k++) {
// if(mp[j][i]==mp[k][i]) {
// for(int l=i+1; l<n; l++) {
// if(mp[j][l]==mp[k][l]) {
// cout<<"NO";
// printf("\n%d %d\n%d %d",j+1,k+1,i+1,l+1);
// goto endd;
// }
// }
// }
// }
// }
// }
///map<pair,int>优化
for(int i=0; i<n; i++) {
for(int j=i+1; j<n; j++) {
map<pair<int,int>,int>vis;
for(int k=0; k<m; k++) {
if(!vis.count(make_pair(mp[k][i],mp[k][j])))
vis[make_pair(mp[k][i],mp[k][j])]=k;
else {
printf("NO\n%d %d\n%d %d\n",vis[make_pair(mp[k][i],mp[k][j])]+1,k+1,i+1,j+1);
goto endd;
}
}
}
}
cout<<"YES\n";
endd:
;
}
return 0;
}