UVa 1592 Database (map)

题意:给出n行m列的数据库(数据范围: n 1~10000, m 1~10), 问你能不能找出两行r1, r2,使得这两行中的c1, c2列是一样的, 即(r1,c1)==(r2,c1) && (r1,c2)==(r2,c2), 可以的话输出NO并且输出r1, r2, c1, c2, 否则输出YES!

 

分析:如果是四个for循环去枚举全部的r1,r2,c1,c2复杂度是O(n*n*m*m),肯定超时!能否减少枚举量?或者只是枚举行或者列?这里可以使用map做到!map的键值设置为一个pair<int, int>存储每一行c1,c2, 第二个值设置为此二元组所在的行, 即map<pair<int,int>,int> == map( <c1, c2>, row ), 这样只要枚举每一行的二元组,然后一行行枚举下去,如果有重复出现的,比如这时候枚举到第i行,然后有其中一个二元组(c1, c2)重复出现,那map[make_pair(c1, c2)]就是之前第一次出现此二元组的行数,第二次出现的行数便是i了!其中可以使用map当类似哈希效果的作用,即将string转化成int, 提取字符串也可以用到stringstream类来进行, 不过这里要注意如果需要有一些空格需要保留(即关键字里面本来就有空格字符),解决方法就是将其填充为一个不可能的字符呀!然后将' , '变成'   '就OK了!即将' , '作为断点分割字符串, 具体可以查查stringstream的用法, 很强大, 但是很慢, 需要谨慎使用!

 

瞎想:为什么不用set?因为不能知道第一次出现二元组的行数呀!

           能不能行列颠倒来枚举?不可以!

 

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<set>
#include<map>
#include<sstream>
#include<math.h>
using namespace std;
map<pair<int, int>, int> sqare;
map<string, int> M;
int G[10001][11];
int num = 0;
int Getid(string s)
{
    if(M.count(s)) return M[s];
    return M[s] = num++;
}
int main(void)
{
    int n, m;
    while(scanf("%d%d", &n, &m)==2){
        getchar();
        M.clear();
        num = 0;
        sqare.clear();
        int j = 0;
        for(int i=0;i<n;i++){
            j = 0;
            string tmp;
            getline(cin, tmp);
            for(int k=0; k<tmp.length(); k++){
                if(tmp[k]==',') tmp[k] = ' ';
                else if(tmp[k]==' ') tmp[k] = '}';
            }
            stringstream s;
            s<<tmp;
            string temp;
            while(s>>temp){
                G[i][j++] = Getid(temp);
            }
        }
//        for(int ii=0; ii<n; ii++){
//            for(int jj=0; jj<m; jj++){
//                printf("%d ", G[ii][jj]);
//            }
//            puts("");
//        }
        int index = -1, i, k;
        for(j=0; j<m-1; j++){//注意枚举的顺序!我一开始就盖了个0~n的傻逼循环
            for(k=j+1; k<m; k++){
                sqare.clear();//注意clear(),因为这个位置的二元组已经枚举完了,没有       我们想要的!
                for(i=0; i<n; i++){
                    if(sqare.count(make_pair(G[i][j], G[i][k]))){
                        index = sqare[make_pair(G[i][j], G[i][k])];
                        break;
                    }
                    sqare[make_pair(G[i][j], G[i][k])] = i;
                }
                if(index!=-1) break;
            }
            if(index!=-1) break;
        }
        if(index==-1) puts("YES");
        else{
            puts("NO");
            printf("%d %d\n", index+1, i+1);
            printf("%d %d\n", j+1, k+1);
        }
    }
    return 0;
}     
View Code

 

         

posted @ 2017-05-17 22:21  qwerity  阅读(182)  评论(0编辑  收藏  举报