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;
}
原文地址:https://www.cnblogs.com/JinxiSui/p/9740635.html