# UVa 1592 - Database
---
# 題目大意
共n行,每行有m個用逗點隔開的字串,問你有沒有某兩列和某兩行的交點的字串分別相等(一行中有兩個一樣,然後另一行同個位置也一樣)。
簡單來說,就是問是否有兩列r1,r2及兩行c1,c2滿足(r1,c1)=(r1,c2)且(r2,c1)=(r2,c2)。
---
# 題解
用map給字串賦值以及檢查重複,因為只要將數字乘一個夠大的數加上另一數就不會重複,所以可以用數字檢查是否有重複出現的字串。接下來因為m很小,所以直接暴力枚舉所有行的組合,並檢查每一列是否有重複出現的字串。
---
```=C++
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pf push_front
#define ft first
#define sec second
#define pr pair<int,int>
#define ISCC ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int n ,m ,g[10005][15] ,ok;
string s ,tp;
int main()
{
while(cin >> n >> m)
{
getchar(); //吃掉cin後的換行
map<string ,int> mp;
ok = 0;
for(int i=0 ,k=0 ;i<n ;i++)
{
getline(cin,s);
tp = ""; k = 0;
for(int j=0 ;j<s.size() ;j++) //用逗點切割字串
{
if(s[j]==',')
{
if(mp.count(tp)) g[i][k++] = mp[tp];
else g[i][k++] = mp[tp] = mp.size();
tp = "";
}
else tp += s[j];
}
if(mp.count(tp)) g[i][k++] = mp[tp]; //逗點都在句中所以最後要再做一次
else g[i][k++] = mp[tp] = mp.size();
}
map<ll ,int> vis;
ll hs;
for(int j=0 ;j<m && !ok ;j++)
for(int k=j+1 ;k<m && !ok ;k++)
{
vis.clear();
for(int i=0 ;i<n ;i++)
{
hs = g[i][j]*1e6 + g[i][k]; //字串種類最多只有1e4*10
if(vis.count(hs))
{
cout << "NO\n" << vis[hs]+1 << ' ' << i+1 << '\n' << j+1 << ' ' << k+1 << '\n';
ok = 1; break;
}
else
vis[hs] = i;
}
}
if(!ok) cout << "YES\n";
}
return 0;
}
```