UVA 1592(Database)

2018-06-05  本文已影响0人  myleosu

思路:参照紫书,先将字符串映射成数字便于处理,然后枚举每两列,再枚举每一行,利用STL里面的map做一个查找,若找到即输出当前行和map存放的之前的那一行即可。
注意:二元组用pair做批处理,代码做了相应注释,(代码参考了两位大佬的做法%%)

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <map>

using namespace std;

typedef pair<int,int>two_data;  //二元组,做批处理
//pair: pair可以理解为定义了一个pair结构体并且里面放置了first,secon两个数据,类型自定如现在的为两个int数据。
//make_pai(): 定义一个pair并放置两个数据进去
int cnt = 0;
map<string,int>id_table;        //将字符串映射成数字的map
map<two_data,int>check;         //根据二元组查找
int id_num[10010][20];          //存字符串映射后的数字

int ID(string s){               //将字符映射为数字函数
    if(id_table.count(s))
        return id_table[s];
    return id_table[s] = cnt++;
}

int main()
{
    //freopen("text.txt","r",stdin);
    int n,m;
    while(cin>>n>>m){
        cnt = 0;
        getchar();              //吸收前一行输入的换行符
        int ch;
        for(int i = 0;i<n;i++){
            for(int j = 0;j<m;j++){
                string x;
                while((ch = getchar())!=EOF&&ch!=','&&ch!='\n') //处理数据,以文件尾和,和换行符为分界
                    x+=ch;
                id_num[i][j] = ID(x);
            }
        }
        bool flag = false;
        for(int i = 0;i<m-1;i++){
            for(int j = i+1;j<m;j++){
                check.clear();                                  //清空当前i,j存放的map
                for(int k = 0;k<n;k++){
                    two_data x = make_pair(id_num[k][i],id_num[k][j]);
                    if(check.count(x)){                         //查找成功,输出结果并退出
                        printf("NO\n");
                        printf("%d %d\n",check[x]+1,k+1);
                        printf("%d %d\n",i+1,j+1);
                        flag = true;
                    }
                    else{
                        check[x] = k;
                    }
                    if(flag) break;
                }
                if(flag) break;
            }
            if(flag) break;
        }
        if(!flag)
            printf("YES\n");
    }
    return 0;
}

上一篇 下一篇

猜你喜欢

热点阅读