例题5-9 UVA1592 数据库 Database

难度:3

首先题意,如果能找到两行两列对应相等,那么输出no,然后输出对应的行列,如果找不到,那么输出yes,

然后是思路,暴力的算法是四重循环,枚举两个列两个行,这样会超时,由于行数比较多,从它开始优化,先枚举两个列,然后枚举一行,把这行的两个数据当成一个整体,从map映射里面看能不能找到,不能,那么就映射成行数,能找到,说明先前出现过了,值就是上一次出现的行数,那么此时再加上当前行就可以输出了

最后是一个细节处理,枚举每一行的时候都有两个数据,我们要比较,如果是字符串的话比较慢,所以输入的时候做处理,给每个字符串分配一个数字id,这样比较的时候就是两个整数和两个整数比较,加快速度。

最后有一个需要注意的点,那就是二元整数对行数的映射要写在什么位置,是枚举两列的循环里面,不能写在外面

#include 

#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pa;

vector<string> vec;
map<string, int> mp;

int getid(string &s) {
    if (mp.find(s) != mp.end()) return mp[s];
    vec.pb(s);
    return mp[s] = (int) vec.size() - 1;
}

int main() {
    int n, m;
    while (cin >> n >> m) {
        getchar();
        int a[10005][15];
        string s;
        for (int i = 0; i < n; i++) {
            getline(cin, s);
            for (int j = 0; j < (int) s.size(); j++) {
                if (s[j] == ' ') s[j] = '_';
                if (s[j] == ',') s[j] = ' ';
            }
            stringstream ss(s);
            string t;
            int cur = 0;
            while (ss >> t) {
                a[i][cur++] = getid(t);
            }
        }
        int ok = 0;
        for (int c1 = 0; c1 < m; c1++) {
            for (int c2 = c1 + 1; c2 < m; c2++) {
                map<pa, int> mp2;
                for (int r = 0; r < n; r++) {
                    pa p = make_pair(a[r][c1], a[r][c2]);
                    if (mp2.find(p) == mp2.end()) mp2[p] = r;
                    else {
                        ok = 1;
                        cout << "NO\n";
                        cout << mp2[p] + 1 << " " << r + 1 << endl;
                        cout << c1 + 1 << " " << c2 + 1 << endl;
                        break;
                    }
                }
                if (ok) break;
            }
            if (ok) break;
        }
        if (!ok) cout << "YES\n";
    }
    return 0;
}

你可能感兴趣的:(#,第5章)