UVa - 1592 Database(STL综合,强推!)

来源:互联网 发布:在淘宝代运营公司工作 编辑:程序博客网 时间:2024/05/17 01:25

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51293

#include <iostream>#include <map>#include <vector>#include <string>#include <cstdio>#include <cstring>#define MAXN 10005#define MAXM 15using namespace std;/*************************************************************************************************************        题意:        给一个数据库,查找是否存在(r1,c1)=(r2,c1) && (r1,c2)=(r2,c2),即:不同的二行,对应二列字符串相同        解题:      1. 首先读入字符串,将每个字符串分配一个编号,这样在遍历数据库查找时会迅速很多,不用比较字符串比如对于            3 3            How to compete in ACM ICPC,Peter,peter@neerc.ifmo.ru            How to win ACM ICPC,Michael,michael@neerc.ifmo.ru            Notes from ACM ICPC champion,Michael,michael@neerc.ifmo.ru            编号为            0 1 2            3 4 5            6 4 5      2. 因为要找到两对相同的列,四重遍历可以找到,但是太慢了,考虑将c1,c2两列的内容一起存到map中,           所以map的key为(x,y)【x,y分别代表对应字符串的编号】,map的值为对应的行r1,遍历行就是r2;           所以三重遍历即可完成。        注意:        1. 注意要找到的二列,不一定相邻,可以相隔;        2. 对于map<node,int> data; data.clear()的位置要放对,每次遍历完2列,           就要清空一次(因为要找到对应两行两列(r1,c1)=(r2,c1) && (r1,c2)=(r2,c2) )        编程思路分三步        1,读入数据做映射        2,遍历行,进行判断        3,释放相关空间        未完待续......        1,operator的实现原理        2,map<Node,int,cmp> table_num的实现原理*************************************************************************************************************/struct Node{    int x,y;};struct cmp{    bool operator() (const Node X,const Node Y) const{        if(X.x != Y.x)            return X.x<Y.x;        if(X.y != Y.y)            return X.y<Y.y;        return false;    }};map<string,int> IDcache;vector<string> IDcard;      //终于体会到这个有什么用了,类似不定长数组,用来从小到大给map映射的string赋值id                            //具体见函数 fuc,这个函数在处理这种题很有用!!!char temp[MAXN][100];       //gets(temp[i])来读入每行信息,总共MAXN行信息。gets可以读入空格,较为方便int table[MAXN][MAXM];      //表格行列,值表示该行列的 string在map映射下的 IDint fuc(string x){    if(IDcache.count(x))    return IDcache[x];    IDcard.push_back(x);    return IDcache[x]=IDcard.size()-1;}int main(){    int n,m;    while(cin>>n>>m)    {        //读入datebase信息并作映射,将映射的ID(int),存入table[MAXN][MAXM]中        getchar();        for(int i = 1;i <= n;i ++)            gets(temp[i]);        string s_temp;        for(int i = 1;i <= n;i ++){            int cnt=1;            for(int j = 0;j <= strlen(temp[i]);j ++){                if(temp[i][j] == ',' || j == strlen(temp[i])){      //每列之间有逗号,作为列判断依据                    table[i][cnt++]=fuc(s_temp);       //行数 : i  列数 : cnt                    s_temp.clear();     //存完一次清空临时 s_temp                }                else                    s_temp+=temp[i][j];     //临时存储每列的字符串信息            }        }        //三重循环,两重循环来遍历列。将两列之间的信息(即ID)映射到 map<Node,int,cmp> table_num中        //第三重循环来遍历不同行        int flag=0;        for(int i = 1;i < m;i ++){            for(int j = i+1;j <= m;j ++){                map<Node,int,cmp> table_num;        //在这里定义,实现了注意的第二点,每次重新录入数据并作映射                for(int k = 1;k <= n;k ++){                    Node p;                    p.x=table[k][i];                    p.y=table[k][j];                    if(!table_num.count(p))                        table_num.insert(pair<Node,int> (p, k));       //类似于将两列信息作为整体Node,映射到cmp                    else{                        cout<<"NO"<<endl;                        cout<<table_num[p]<<" "<<k<<endl;                        cout<<i<<" "<<j<<endl;                        flag=1;                        break;                    }                }                if(flag)                    break;            }            if(flag)                break;        }        if(!flag)            cout<<"YES"<<endl;        //一次处理完datebase记得归还空间        memset(table,0,sizeof(table));        memset(temp,0,sizeof(temp));        s_temp.clear();        IDcache.clear();        IDcard.clear();    }    return 0;}


0 0
原创粉丝点击