大概是在10000*10的矩阵里找两行,两列,使得两行中的对应列是相同的。
思路:在长列中hash,建立hash数组,表示这个hash[i]的i前一个位置,建立链表next[i] 指向hash[value[i]],这样就能O(n)的找到所有相同的数的一个链表。
然后搜索两列的时候比较当前指向的位置,当前比较短的跳转。
#include <cstdio>
#include <deque>
#include <set>
#include <string>
#include <map>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
#define Debug(x) (cerr << #x << " = " << (x) << endl)
#define Debug2(x, y) (cerr << #x << " = " << (x) << ", " << #y << " = " << (y) << endl)
template<class T> inline T& RD(T &x){
char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); '0' <= c && c <= '9'; c = getchar()) x = x * 10 + c - '0';
return x;
}
const int inf = 0x3f3f3f3f;
const int maxn = 10005;
map<string,int> mymap;
int mat[maxn][11];
int vis[maxn*11];
int next[maxn][11];
void solve(int n, int m){
for(int i=0;i<m;i++){
memset(vis,-1,sizeof(vis));
for(int j=0;j<n;j++){
int t = mat[j][i];
next[j][i] = vis[t];
vis[t] = j;
}
}
/*
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
printf("%d ", next[i][j]);
}
printf("\n");
}
*/
for(int j=0;j<m;j++){
for(int k=j+1;k<m;k++){
//compare next[][j] & next[][k]
for(int i=n-1;i>=0;i--){
int i1=i,i2=i;
while(next[i1][j] != -1 && next[i2][k] != -1){
if(next[i1][j] > next[i2][k]){
i1 = next[i1][j];
}
else if(next[i1][j] == next[i2][k]){
printf("NO\n%d %d\n%d %d\n",next[i1][j]+1,i+1,j+1,k+1);
return;
}
else {
i2 = next[i2][k];
}
}
}
}
}
printf("YES\n");
}
int main(){
string str;
int n,m;
char ch;
//freopen("in","r",stdin);
while(~scanf("%d%d",&n,&m)){
mymap.clear();
ch = getchar();
str = "";
int tot = 1;
for(int i=0;i<n;i++){
int cnt = 0;
while(ch = getchar()){
if(ch == ',' || ch == '\n'){
if(mymap[str] == 0){
mymap[str] = tot;
mat[i][cnt] = tot;
cnt ++;
tot ++;
}
else{
mat[i][cnt] = mymap[str];
cnt ++;
}
str = "";
if(ch == '\n')break;
}
else str += ch;
}
}
solve(n,m);
}
return 0;
}