Database UVA - 1592
对于每组数据,首先通过一个map将每个字符串由一个数字代替,相同的字符串由相同数字代替,不同的字符串由不同数字代替。那么题目就变为了询问是否存在行r1,r2以及列c1,c2使得str[r1][c1]=str[r2][c1]且str[r1][c2]=str[r2][c2](此时所有单元格内都是数字,str[i][j]表示第i行第j列的数字)。也就是寻找两行和两列,它们相交所在的四个单元格中上面的两个与下面两个分别相等。
然后,由于行多列少,可以枚举列。对于每次枚举出的两列c1,c2,先清空map,然后从上往下扫描行。设当前扫描到的行是第k行,则建立二元组(str[k][c1],str[k][c2]),如果map中没有此二元组则将其放入map,并将值设为k;如果map中有此二元组,则表示前面有某行的c1,c2两列与这一行的c1,c2两列分别相同,那么由存入map的方法可知map[二元组]得到"某行",显然r1就是"某行",r2就是k,c1,c2就是枚举出的c1,c2。
#include<vector> #include<map> #include<string> #include<iostream> using namespace std; int n,m; int str[10001][11]; typedef pair<int,int> P; int now; map<string,int> IDcache;//根据字符串取ID map<P,int> m2;//存储由二元组映射到行号 void getstring(string& s) { s=""; int a=getchar(); while(a=='\n') a=getchar(); while(a!='\n'&&a!=',') { s+=(char)a; a=getchar(); } } int main() { string s1; P p1; int i,j,k; bool flag; while(cin>>n>>m) { flag=false; now=0; IDcache.clear(); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { getstring(s1); if(IDcache.count(s1)==1) str[i][j]=IDcache[s1]; else { IDcache[s1]=(++now); str[i][j]=now; } } // for(i=1;i<=n;i++) // for(j=1;j<=m;j++) // cout<<str[i][j]<<'\n'; for(i=1;i<m;i++) for(j=i+1;j<=m;j++) { m2.clear(); for(k=1;k<=n;k++) { //goto不应该乱用,但是跳出很多重循环可以用以简化程序 //https://baike.baidu.com/item/goto%E8%AF%AD%E5%8F%A5 p1=P(str[k][i],str[k][j]); if(m2.count(p1)==1) { flag=true; cout<<"NO\n"; cout<<m2[p1]<<' '<<k<<'\n'; cout<<i<<' '<<j<<'\n'; goto lab; } else m2[p1]=k; } } lab: if(flag==false) cout<<"YES\n"; } return 0; }