• 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
    ", index+1, i+1);
                printf("%d %d
    ", j+1, k+1);
            }
        }
        return 0;
    }     
    View Code

             

  • 相关阅读:
    转 intent常用功能
    Android 中Activity生命周期分析(二):从AActivity 到BActivity过程分析
    Android 面试题(经典)
    Android 中Activity生命周期分析:Android中横竖屏切换时的生命周期过程
    ios 开发中 developer tools access 总是要输入密码问题的解决
    【转】android 自定义控件
    【转】项目管理
    程序员的出路
    第一章 Actionscript学习基本知识笔记及flashdevelop软件的安装问题
    第十五章 php时区报错 We selected the timezone 'UTC'
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/6869847.html
Copyright © 2020-2023  润新知