中国科学院软件研究所软件工程技术中心2007年硕士研究生复试上机题

  今年考上中科院软件所了,便把复试时的上机题分享,算法共欣赏,代码相与析。

    题目是这样的:

现在在数据库中保存有这样一张表(电影名:string,演员个数:number,演员名:string),如果演员A和演员B参加了同一部电影1的演播,演员B和演员C参加了另一个电影2的演播,而演员C和演员D参加了电影3的演出,那么,我们认为演员A和演员D之间存在友情联接,并定义这种联接的长度为3。请用C/C++/Java给出算法,找出所有演员的联接长度恰好为3的友情演员。

例如,有6部电影,信息如下:

1.Mission Impossible 3》,演员3人,分别为:Tom CruiseMaggie QJeff Chase

2.War Of The Worlds》,演员2人,分别为:Tom CruiseDakota Fanning

3.Shark Tale》演员3人,分别为:Jack BlackRobert DeNiroWill Smith

4.Hide And Seek》,演员2人,分别为:Dakota FanningRobert DeNiro

5.The Adventure Of Pluto Nash》,演员2人,分别为:Will SmithEddie Murphy

6.Show Time》,演员2人,分别为:Robert DeNiroEddie Murphy

那么,请程序打印出这些演员的联接长度恰好为3的友情演员清单

 

我使用的算法是双向广度优先搜索,先把所有的演员放在集合中,然后用两个for循环遍历,判断任意两个演员之间是否存在长度为3的连接,若存在,就打印出来。代码如下(使用标准C++和STL):

 

#include <map>
#include <set>
#include <functional>
#include <algorithm>
#include <iterator>
#include <functional>
#include <string>
#include <fstream>
#include <iostream>

using namespace std;

class CProblem 
{
public:
    void Print();
    void Solve();
 void GetFilm(string Actor,set<string>& FilmSet);
 void GetLink1(string Actor,set<string>& ActorSet);
 bool IsLink3(string actor1,string actor2);
 CProblem(char* filename);
 virtual ~CProblem();
protected:
 multimap<string,string,less<string> >ActorFilmMap;
 set<string>ActorSet;
};

CProblem::CProblem(char* filename)
{
 ifstream fin(filename);
 if(!fin)
 {
  cerr<<"File not open!"<<endl;
  exit(1);
 }
 string ActorName,FilmName;
 int ActorNum;
 while(getline(fin,FilmName,'/n'))
 {
  fin>>ActorNum;
  getline(fin,ActorName,'/n');
  for(int i=0;i<ActorNum;i++)
  {
            getline(fin,ActorName,'/n');
   ActorFilmMap.insert(make_pair(ActorName,FilmName));
   ActorSet.insert(ActorName);
  }
        getline(fin,FilmName,'/n');
 }
 fin.close();
}

CProblem::~CProblem()
{

}

bool CProblem::IsLink3(string actor1, string actor2)
{
     set<string>ActorSet1,ActorSet2;
     GetLink1(actor1,ActorSet1);
     GetLink1(actor2,ActorSet2);
    
     set<string>::iterator Iter1,Iter2;
     for(Iter1=ActorSet1.begin();Iter1!=ActorSet1.end();Iter1++)
         for(Iter2=ActorSet2.begin();Iter2!=ActorSet2.end();Iter2++)
         {
             if(*Iter1!=*Iter2 && actor1!=*Iter2 && actor2!=*Iter1)
             {
                 set<string,less<string> >FilmSet1,FilmSet2;
                 GetFilm(*Iter1,FilmSet1);
                 GetFilm(*Iter2,FilmSet2);
                
                 set<string>::iterator Iter3,Iter4;
                 for(Iter3=FilmSet1.begin();Iter3!=FilmSet1.end();Iter3++)
                     for(Iter4=FilmSet2.begin();Iter4!=FilmSet2.end();Iter4++)
                         if(*Iter3==*Iter4)
                             return true;
             }
         }
 return false;
}

void CProblem::GetLink1(string Actor,set<string>& ActorSet)
{
     set<string>FilmSet;
     GetFilm(Actor,FilmSet);
    
     set<string>::iterator Iter1;
     multimap<string,string>::iterator Iter2;
     for(Iter1=FilmSet.begin();Iter1!=FilmSet.end();Iter1++)
     for(Iter2=ActorFilmMap.begin();Iter2!=ActorFilmMap.end();Iter2++)
     {
     if(*Iter1==Iter2->second && Actor!=Iter2->first)
     ActorSet.insert(Iter2->first);
     }
    
}

void CProblem::GetFilm(string Actor,set<string>& FilmSet)
{
     multimap<string,string>::iterator Iter1;
     for(Iter1=ActorFilmMap.lower_bound(Actor);Iter1!=ActorFilmMap.upper_bound(Actor);Iter1++)
     {
     FilmSet.insert(Iter1->second);
     }
}

void CProblem::Solve()
{
     set<string>::iterator Iter1,Iter2;
     for(Iter1=ActorSet.begin();Iter1!=ActorSet.end();Iter1++)
     {
         for(Iter2=ActorSet.begin();Iter2!=ActorSet.end();Iter2++)
         {
             if(*Iter2==*Iter1)
                 continue;
             if(IsLink3(*Iter1,*Iter2))
                 cout<<*Iter1<<" and "<<*Iter2<<" are of link 3."<<endl;
         }
         cout<<endl;
     }
}

void CProblem::Print()
{
     multimap<string,string>::iterator Iter1;
     for(Iter1=ActorFilmMap.begin();Iter1!=ActorFilmMap.end();Iter1++)
     cout<<Iter1->first<<" "<<Iter1->second<<endl;
}
int main()
{
    CProblem prob("data.txt");
   prob.Solve();
   
    system("PAUSE");
    return 0;
}

/

data.txt:

MissionImpossible3
3
TomCruise
MaggieQ
JeffChase

WarOfTheWorlds
2
TomCruise
DakotaFanning

SharkTale
3
JackBlack
RobertDeNiro
WillSmith

HideAndSeek
2
DakotaFanning
RobertDeNiro

TheAdventureOfPlutoNash
2
WillSmith
EddieMurphy

ShowTime
2
RobertDeNiro
EddieMurphy

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值