昨晚上终于把这题AC了,太晚了于是倒头就去睡觉了,现在来写下博客。这题第一开始就没看懂题目,(一直不明白是否会有多个满足题意的行、列,如果有,按题目说的只有两行的话输出具体哪一个满足题意的也并没有指出,于是很是困惑,不过后来找到了WA的原因后觉得可能数据中就是有多个满足题意的,只输出一个就好了)后来还是没懂,按照书上思路写了代码之后WA,于是开始调,一点点的用标程中的代码块替换自己的,替换之后提交,发现WA后,把这段代码该回自己的,再用标程的另一个程序块替换自己程序中等价的部分,最后终于AC了,并且找到了自己的错误。
先发下自己没有修改前的WA版代码:
#include <cstdio>
#include <iostream>
#include <map>
#include <cstring>
#include <vector>
#include <sstream>
using namespace std;
//struct Row
//{
// int r1,r2;
// void row()
// {
// r1 = r2 = 0;
// }
// bool operator < (const Row& rr) const
// {
// if(r1 < rr.r1) return true;
// else return false;
// }
//};
typedef pair<int,int> PII;
int idcnt;
string str, substring;
vector<int> data[15];
map<string, int> id;
map<PII, int> enumrow;
void strcut(int);
int main()
{
freopen("New Text Document.txt","r",stdin);
freopen("Output.txt","w",stdout);
ios::sync_with_stdio(false);
int n, m;
while(cin>>n>>m)//之前此处用了scanf后面用的getline 导致程序出错
{
bool flag = true;
cin.get();
idcnt = 0;
for(int i = 0; i < n; i++)
{
getline(cin, str);
//cout<<str<<endl;
strcut(i);//传递所在行数i
}
for(int i = 0; i < m; i++)
for(int j = i+1; j < m; j++)
{
enumrow.clear();
for(int k = 1; k < n; k++)
{
PII row = make_pair(data[i][k], data[j][k]);
if(!enumrow.count(row))
enumrow[row] = k;
else
{
int rr = enumrow[row];
printf("NO\n%d %d\n%d %d\n", rr+1, k+1, i+1, j+1);
flag = false;
break;
}
}
}
if(flag) printf("YES\n");
}
return 0;
}
void strcut(int i)
{
int j = 0, k, cnt = 0;
for(k = 0; k < str.length(); k++)
if(str[k] == ',')//一开始写成了字符与字符串比较 str[k] == ","
{
substring = str.substr(j, k-j);
j = k+1;
if( !id.count(substring) ) id[substring] = ++idcnt;
data[cnt++].push_back(id[substring]);
}
substring = str.substr(j, str.length()-j);
if( !id.count(substring) ) id[substring] = ++idcnt;
data[cnt++].push_back(id[substring]);
}
这一版代码我已经修改了一些非程序设计方面的错误,例如scanf与getline同时在程序中出现导致的读入错误(scanf比getline快,于是不能保证在scanf前的getline能正确读入该行数据),还有就是pair的用法,自己之前用了一个结构体,不知道C++中有这样一个pair并且有make_pair函数,还是大大简便了的,这里有我在网上看的关于pair用法的网页:http://blog.csdn.net/huang_xw/article/details/8201671
还是挺不错的
下面是我的下一个修改版:(也是错的)中间我套用了一些刘汝佳的标程来检查。
#include <cstdio>
#include <iostream>
#include <map>
#include <cstring>
#include <vector>
#include <sstream>
using namespace std;
typedef pair<int,int> PII;
int idcnt, n, m;
string str, substring;
vector<int> data[15];
map<string, int> id;
map<PII, int> enumrow;
void strcut(int);
int ID(const string& s) {
if(!id.count(s)) {
id[s] = ++idcnt;
}
return id[s];
}
void find() {
for(int c1 = 0; c1 < m; c1++)
for(int c2 = c1+1; c2 < m; c2++) {
map<PII, int> d;
for(int i = 0; i < n; i++) {
PII p = make_pair(data[c1][i], data[c2][i]);
if(d.count(p)) {
printf("NO\n");
printf("%d %d\n", d[p]+1, i+1);
printf("%d %d\n", c1+1, c2+1);
return;
}
d[p] = i;
}
}
printf("YES\n");
}
int main()
{
freopen("New Text Document.txt","r",stdin);
freopen("Output.txt","w",stdout);
ios::sync_with_stdio(false);
while(getline(cin, str))//֮ǰ´Ë´¦ÓÃÁËscanfºóÃæÓõÄgetline µ¼Ö³ÌÐò³ö´í
{
stringstream ss(str);
if(!(ss >> n >> m)) break;
bool flag = true;
cin.get();
idcnt = 0;
for(int i = 0; i < n; i++)
{
getline(cin, str);
strcut(i);//´«µÝËùÔÚÐÐÊýi
}
// for(int i = 0; i < m; i++)
// for(int j = i+1; j < m; j++)
// {
// enumrow.clear();
// for(int k = 1; k < n; k++)
// {
// PII row = make_pair(data[i][k], data[j][k]);
// if(!enumrow.count(row))
// enumrow[row] = k;
// else
// {
// int rr = enumrow[row];
// printf("NO\n%d %d\n%d %d\n", rr+1, k+1, i+1, j+1);
// flag = false;
// break;
// }
// }
// }
// if(flag) printf("YES\n");
find();
}
return 0;
}
void strcut(int i)
{
//int j = 0, k, cnt = 0;
// for(k = 0; k < str.length(); k++)
// if(str[k] == ',')//Ò»¿ªÊ¼Ð´³ÉÁË×Ö·ûÓë×Ö·û´®±È½Ï str[k] == ","
// {
// substring = str.substr(j, k-j);
// j = k+1;
// if( !id.count(substring) ) id[substring] = ++idcnt;
// data[cnt++].push_back(id[substring]);
// }
// substring = str.substr(j, str.length()-j);
// if( !id.count(substring) ) id[substring] = ++idcnt;
// data[cnt++].push_back(id[substring]);
int lastpos = -1;
for(int j = 0; j < m; j++) {
int p = str.find(',', lastpos+1);
if(p == string::npos) p = str.length();
data[j].push_back( ID(str.substr(lastpos+1, p - lastpos - 1)) );
lastpos = p;
}
}
这个是我的最终AC版错误具体在何处参见下面代码中的注释,就是由于如果是NO,输出完三行后没有停止循环,可能输出了别的解导致(个人认为)。
#include <cstdio>
#include <iostream>
#include <map>
#include <cstring>
#include <vector>
#include <sstream>
using namespace std;
typedef pair<int,int> PII;
int idcnt;
int n, m;
string str, substring;
int data[10010][15];
map<string, int> id;
map<PII, int> enumrow;
void strcut(int);
int main()
{
freopen("New Text Document.txt","r",stdin);
freopen("Output.txt","w",stdout);
ios::sync_with_stdio(false);
while(cin>>n>>m)//之前此处用了scanf后面用的getline 导致程序出错
{
bool flag = true;
cin.get();
idcnt = 0;
for(int i = 0; i < n; i++)
{
getline(cin, str);
strcut(i);//传递所在行数i
}
for(int i = 0; i < m; i++)
{
for(int j = i+1; j < m; j++)
{
enumrow.clear();
for(int k = 0; k < n; k++)
{
PII row = make_pair(data[k][i], data[k][j]);
if(!enumrow.count(row))
enumrow[row] = k;
else
{
int rr = enumrow[row];
printf("NO\n%d %d\n%d %d\n", rr+1, k+1, i+1, j+1);
flag = false;
break;
}
}
if(!flag) break; //最开始没写这句还有下面这个break一直WA
}
if(!flag) break;//这句 我认为或许没有这两个会输出很多组不同的,因此会WA
}
if(flag) printf("YES\n");
}
return 0;
}
void strcut(int i)
{
int j = 0, k, cnt = 0;
for(k = 0; k < str.length(); k++)
if(str[k] == ',')//一开始写成了字符与字符串比较 str[k] == ","
{
substring = str.substr(j, k-j);
j = k+1;
if( !id.count(substring) ) id[substring] = ++idcnt;
data[i][cnt++] = id[substring];
}
substring = str.substr(j, str.length()-j);
if( !id.count(substring) ) id[substring] = ++idcnt;
data[i][cnt++] = id[substring];
}
下面贴出来刘汝佳标程。
对于标程中用到的string::npos不理解的可以看看下面这两个网址,或许有收获。
http://blog.sina.com.cn/s/blog_7dc67d520101muci.html
http://www.tuicool.com/articles/Unu2Yf
// UVa1592 Database
// Rujia Liu
// 本程序只是为了演示STL各种用法,效率较低。实践中一般用C字符串和哈希表来实现。
#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<map>
#include<sstream>
using namespace std;
typedef pair<int,int> PII;
const int maxr = 10000 + 5;
const int maxc = 10 + 5;
int m, n, db[maxr][maxc], cnt;
map<string, int> id;
int ID(const string& s) {
if(!id.count(s)) {
id[s] = ++cnt;
}
return id[s];
}
void find() {
for(int c1 = 0; c1 < m; c1++)
for(int c2 = c1+1; c2 < m; c2++) {
map<PII, int> d;
for(int i = 0; i < n; i++) {
PII p = make_pair(db[i][c1], db[i][c2]);
if(d.count(p)) {
printf("NO\n");
printf("%d %d\n", d[p]+1, i+1);
printf("%d %d\n", c1+1, c2+1);
return;
}
d[p] = i;
}
}
printf("YES\n");
}
int main() {
string s;
while(getline(cin, s)) {
stringstream ss(s);
if(!(ss >> n >> m)) break;
cnt = 0;
id.clear();
for(int i = 0; i < n; i++) {
getline(cin, s);
int lastpos = -1;
for(int j = 0; j < m; j++) {
int p = s.find(',', lastpos+1);
if(p == string::npos) p = s.length();
db[i][j] = ID(s.substr(lastpos+1, p - lastpos - 1));
lastpos = p;
}
}
find();
}
return 0;
}