题目要求:
有n个人,每个人都有各自的好友列表。给定一个阈值p,当A和B的共同好友数超过p则推荐A和B为好友。请实现自动推荐直到没有好友可以推荐(每次推荐默认同意,即一定成为好友),然后进行一些查询。
查询1:A的好友数有几个?如果A不在这n个里面,输出-1,否则输出好友数;
查询2:A和B是好友吗?如果是则输出0,否则输出-1。
输入:p n m x y
p为阈值,n为人数,m为初始时的好友,x为查询1的个数,y为查询2的个数
注: - 如果A是B的好友,B一定是A的好友; - 每个人的人名用不超过20个字符的字符串表示,没有重名的人; - 人数不超过100.
输入示例:
2 3 3 3 3
A
B
C
A B
B C
A C
A
B
C
A B
C A
B C
应输出:
2
2
2
0
0
0
我的思路:
1.根据输入的好友数量N,建立一个N*N的关系矩阵,1表示为好友,0表示非好友关系。这样做的好处是便于保存和修改好友关系。注意点:每次修改时要对m,n和n,m两个位置的元素进行修改;对第i行遍历时从第i+列开始即可。
2.好友推荐处理过程就是对关系矩阵的处理,遍历矩阵每一行,当为非好友时,通过矩阵算出共同好友数;为好友时,跳过;当共同好友数超过阈值时将值设为1。直到关系矩阵不再被改变为止,此时已无可推荐好友了。
3.基于处理后的关系矩阵,根据输入的查询进行计算即可。
#include<string> #include<iostream> #include<vector> #include<algorithm>//用到其中的find()函数,返回迭代器或指针 using namespace std; int friendnum(vector<int> &R,vector<string> &namelist, string name,int N) { int loc=find(namelist.begin(),namelist.end(),name)-namelist.begin(); int count=0; if(loc>N-1) count=-1; else { for(int i=0;i<N;i++) if(R[loc*N+i]==1) count++; } return count; } int isfriend(vector<int> &R,vector<string> &namelist, string name1,string name2,int N) { int loc1=find(namelist.begin(),namelist.end(),name1)-namelist.begin(); int loc2=find(namelist.begin(),namelist.end(),name2)-namelist.begin(); int count=-1; if(loc1>N-1||loc2>N-1) count=-1; else { if(R[loc1*N+loc2]==1) count=0; } return count; } void main() { while(1) { vector<string> namelist; string nametemp; int P,N,M,X,Y; cin.clear(); cin.sync(); cin>>P>>N>>M>>X>>Y; vector<int> R(N*N,0);//建立关系矩阵,默认为0,非好友 int n=N;//人数 while(n--)//建立姓名列表 { cin>>nametemp; namelist.push_back(nametemp); } int m=M; string name1,name2; int name1_it,name2_it; while(m--)//填充关系矩阵 { cin>>name1>>name2; name1_it=find(namelist.begin(),namelist.end(),name1)-namelist.begin();//注意string.find()返回的是下标,而find()返回的是迭代器,用find()函数在容器中获得下标方法find(vec_aa.begin(),vec_aa.end(),2)-vec_aa.begin();没有找到时返回值超过边界。 name2_it=find(namelist.begin(),namelist.end(),name2)-namelist.begin();//似乎string不需要用到迭代器,可返回下标,也可使用下标。string.back()是什么鬼? R[name1_it*N+name2_it]=1; R[name2_it*N+name1_it]=1; } //显示初始好友关系矩阵。1:好友;2:非好友 //for(int i=0;i<N;i++) //{ // for(int j=0;j<N;j++) // cout<<R[N*i+j]<<' '; // cout<<endl; //} //好友推荐过程 int flag=1; while(flag) { flag=0;//用于判断是否结束推荐 for(int i=0;i<N;i++) { for(int j=i+1;j<N;j++) { if(R[N*i+j]!=1)//不是好友 {//判断是否符合推荐阈值 int count=0; for(int k=0;k<N;k++) if(R[N*i+k]==R[N*j+k])//k为其共同好友 count++; if(count>=P)//达到阈值 { R[N*i+j]=1;//成为相互间的好友 R[N*j+i]=1;//修改关系矩阵 } flag=1;//有推荐改动,继续推荐循环 } } } } //显示好友推荐完成后的好友关系矩阵。1:好友;2:非好友 //for(int i=0;i<N;i++) //{ // for(int j=0;j<N;j++) // cout<<R[N*i+j]<<' '; // cout<<endl; //} //cout<<"x y="<<X<<' '<<Y<<endl; //推荐结束,响应查询 vector<int> qury1; //查询1答案记录 int x=X; int y=Y; while(x--) { string tempqury; cin>>tempqury; int tempans=friendnum(R, namelist, tempqury, N); qury1.push_back(tempans); } vector<int> qury2; //查询2记录 while(y--) { string name1; string name2; cin.sync(); cin.clear(); cin>>name1>>name2; int tempans=isfriend(R, namelist, name1, name2, N); qury2.push_back(tempans); } //输出结果 for(int i=0;i<X;i++) cout<<qury1[i]<<endl; for(int i=0;i<Y;i++) cout<<qury2[i]<<endl; } //int aa[]={1,2,3,4}; //vector<int> vec_aa(aa,aa+4); ////string a=str(str.find("a")); ////string::iterator it=str.find("a"); ////vector<int>::iterator loc=find(vec_aa.begin(),vec_aa.end(),2)-vec_aa.begin(); //int loc=find(vec_aa.begin(),vec_aa.end(),2)-vec_aa.begin(); //cout<<vec_aa[loc]; } //测试集 //输入: //2 3 3 3 3 //A //B //C //A B //B C //A C //A //B //C //A B //C A //B C //应输出: //2 //2 //2 //0 //0 //0
1.find()和string.find()区别:algorithm库中的find()返回的是迭代器,输入三个参数,开始和结束的迭代器,待寻找值。获得下标值得方式是find(.begin(),.end(),xx)-.begin();string.find()返回的是下标值。