天天看點

UVA 1592資料庫詳解 按照紫書上劉汝佳的解題法 利用map和pair(存在多種小細節的改動)

題目連結

本題利用到了一個新的知識點,那就是stl中存在的二進制關系pair,詳情請看pair當然也可以用結構體進行替換;

#include<iostream>
#include<string>
#include<map>
#include<utility>
#include<sstream>
using namespace std;
typedef pair<int,int>IFF;
const int maxr=10000+10;
const int maxn=10+5;
map<string,int>id;
int n,m,cnt;
int db[maxr][maxn];
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<IFF,int>d;
		for(int r=0;r<n;r++)
		{
			IFF p=make_pair(db[r][c1],db[r][c2]);//将第i行的第c1、c2列中字元串所對應的ID臨時組成一個pair
			if(d.count(p))//如果該pair在之前出現過,就說明我們找到了這樣的c1,c2,r1,r2
			{
				cout<<"NO"<<endl;			
				cout<<d[p]+1<<" "<<r+1<<endl;	
				cout<<c1+1<<" "<<c2+1<<endl;
				return;			
			}
			d[p]=r;
		}		
	}	
	cout<<"YES"<<endl;
}
int main()
{
//主函數
	while(cin>>n>>m)
	{
		cnt=0;
		getchar();//注意這裡在清空緩沖區時不能用cin.sync(),否則會運作失敗;[cin詳解](https://blog.csdn.net/selina8921/article/details/79067941)
		id.clear();
		string s;
		for(int i=0;i<n;i++)
	  {
		getline(cin,s);
		int lastpos=0;
		for(int j=0;j<m;j++)
		{
		int location=s.find(',',lastpos);
		if(location==-1) location=s.size();
		db[i][j]=ID(s.substr(lastpos,location-lastpos));
		lastpos=location+1;
		}
	  }
	  find();
	}
	return 0;
}
           

這裡說一下在解決輸入問題時,看大lao第二種方法:

每行都用getline進行輸入,不過第一行的數字利用stringstream輸入流進行截取,實在是妙啊!

//主函數
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=0;
		for(int j=0;j<m;j++)
		{
		int location=s.find(',',lastpos);
		if(location==-1) location=s.size();
		db[i][j]=ID(s.substr(lastpos,location-lastpos));
		lastpos=location+1;
		}
	  }
	  find();
  }
  return 0;
}