# 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; } ```