• UVa


    题目链接: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 15
    using 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映射下的 ID
    
    
    int 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;
    }
    


  • 相关阅读:
    [其他]将Windows Terminal添加到右键菜单
    [VS Code]在自己的Ubuntu服务器上构建VSCode Online
    [Go]goFileView-基于Golang的在线Office全家桶预览
    [Go]基于Go语言的Web路由转发,多个网站共享一个端口(新版本,支持WebSocket)
    [WSL]在Windows10子系统里安装运行桌面(xUbuntu)
    [Go]使用Golang对鸢尾花数据集进行k-means聚类
    [Python+JavaScript]JS调用摄像头并拍照,上传至tornado后端并转换为PIL的Image
    [Python]Python基于OpenCV批量提取视频中的人脸并保存
    [WSL]Windows10 Ubuntu子系统编译安装线程安全版LAMP
    [Go]基于Go语言的Web路由转发,多个网站共享一个端口(存在问题,已经抛弃,新解决方案请看新博客)
  • 原文地址:https://www.cnblogs.com/Jstyle-continue/p/6351975.html
Copyright © 2020-2023  润新知