题意
寻找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;
}