• UVa 1592


    题意

    寻找PNF表格
    如果是PNF表格, 输出一行”YES”
    如果有某两行两列字符串相同, 则不是PNF表格, 那么只输出三行
    第一行 : “NO”
    第二行 : 非PNF的所在行c1,c2
    第二行 : 非PNF的所在列r1,r2

    思路

    用getchar() 读字符(读到’,’)到string中, 这里用个结构体或者二维都行, 个人比较喜欢结构体. 用map映射, 建函数getid()存到一个对应行列数的二维数组中 (getid思想来自于紫书“集合栈计算机”)
    遍历考虑超时问题, 这次超时超的我头皮发麻 !
    题给数据范围 :

    The first line of each dataset contains two integer numbers n and m(1 ≤ n ≤ 10000, 1 ≤ m ≤ 10)
    Each row has at most 80 characters (including separating commas).

    学习了紫书给的减少遍历次数的思路, 这里引用一下

    【分析】
    直接写一个四重循环枚举r1,r2,c1,c2可以吗?理论上可以,实际上却行不通。枚举量太大,程序会执行相当长的时间,最终获得TLE(超时)。
    解决方法是只枚举c1和c2,然后从上到下扫描各行。每次碰到一个新的行r,把c1,c2两列的内容作为一个二元组存到一个map中。如果map的键值中已经存在这个二元组,该二元组映射到的就是所要求的r1,而当前行就是r

    映射map : 键是一对int, 即遍历位置的ID, 值是所在行的行数

    typedef pair<int,int> PR;
    map<PR,int> Find;

    这里注意一下:
    map<键,值> : 多个键应该可以对应一个值 , 一个键不能对应多个值

    遍历遇到非PNF就直接break掉行了 , 之前题意没有读清楚以为所有查到的都输出 , 还想着存成map< int , PR >然后iter迭代…. 后来发现理解错题意了….

    容器用完记得清空!!!

    if( !Find.empty() )     Find.clear();

    还有id也要清

    if( !ID.empty() )   ID.clear();

    当然还有string
    直接初始化空串就行

    for( i = 0; i < m; i++ )
                for( j = 0; j < n; j++ )
                    p[i][j].s = "";

    AC代码

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    
    using namespace std;
    
    map<string,int> ID;
    typedef pair<int,int> PR;
    map<PR,int> Find;
    int num = 0;
    
    int getid( string s )
    {
        if( ID.count(s) )
            return ID[s];
        pair<string,int> p(s,num);
        num++;
        ID.insert(p);
        return ID[s];
    }
    
    struct data
    {
        string s;
        int id_s;
    };
    struct data p[10100][15];
    
    int main()
    {
        int m, n;
        int i, j, k;
        char ch;
        while( ~scanf("%d%d",&m,&n) )
        {
            getchar();
            bool flag = true;
            for( i = 0; i < m; i++ ){
                for( j = 0; j < n; j++ ){
                        while( ch=getchar() ){
                            if( ch == ',' || ch == '
    ')
                                break;
                            p[i][j].s += ch;
                        }
                        p[i][j].s += '';
                        //cout << p[i][j].s << endl;
                        p[i][j].id_s = getid(p[i][j].s);
                }
            }
            for( j = 0; j < n; j++ ){
                for( k = j+1; k < n; k++ ){
                    for( i = 0; i < m; i++ ){
                        PR pr(p[i][j].id_s,p[i][k].id_s);
                        pair<PR,int> pp(pr,i);
                        if( Find.count(pr) ){
                            cout << "NO" << endl;
                            cout << Find[pr]+1 << ' ' << i+1 << endl;
                            cout << j+1 << ' ' << k+1 << endl;
                            flag = false;
                            break;
                        }
                        if(!flag)   break;
                        Find.insert(pp);
                    }
                    if( !Find.empty() )     Find.clear();
                    if(!flag)   break;
                }
                if(!flag)   break;
            }
            if( flag )  cout << "YES" << endl;
            /*  ---------  */
            if( !ID.empty() )   ID.clear();
            for( i = 0; i < m; i++ )
                for( j = 0; j < n; j++ )
                    p[i][j].s = "";
            num = 0;//每组测试结束后 还原全局变量num的值
        }
        return 0;
    }
  • 相关阅读:
    c# 改变FileUpload 上传文件大小
    使用ActiveX读取客户端mac地址
    javascript小技巧
    【2012百度之星/资格赛】H:用户请求中的品牌 [后缀数组]
    POJ1012 约瑟夫环问题[双向循环链表+打表技巧]
    北大ACM题分类
    ACM大量习题题库
    POJ1423 计算出n的阶乘的位数大数问题[Stirling公式]
    ACM训练计划(下)
    POJ2080 角度问题[cmath函数]
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740635.html
Copyright © 2020-2023  润新知