我们规定一个人是复读机当且仅当他说的每一句话都是复读前一个人说的话。
我们规定一个人是复读机当且仅当他说的每一句话都是复读前一个人说的话。
我们规定一个人是复读机当且仅当他说的每一句话都是复读前一个人说的话。
规定一个复读机的熟练度为复读数量的多少。现在给你一段聊天记录,请你找出其中的复读机们。
规定一个复读机的熟练度为复读数量的多少。现在给你一段聊天记录,请你找出其中的复读机们。
规定一个复读机的熟练度为复读数量的多少。现在给你一段聊天记录,请你找出其中的复读机们。
输入格式
输入T组,(1≤T
每组第一行输入一个正整数N,表示聊天记录的长度(1≤N。
接下来N行,每行两个字符串,前一个字符串为姓名,后一个字符为聊天记录。
保证所有字符串长度不超过50,保证所有字符串只包含小写字母.
输出格式
如果没有复读机,输出 “Unbelievable!”(不包含引号)
否则按照熟练度从大到小输出所有的复读机,如果熟练度相同,按照字典序从小到大输出。
样例
Input
1 4 codancer iamsovegetable dicer iamsovegetable todest iamsovegetable capryang iamsovegetable
Output
capryang dicer todest
提示
数据保证上面大佬们说的话都是瞎话。
刚看到这个题目的时候觉得还可以,可以写写看,,然后扣了将近两个小时也没写出来,后来听别人说的时候发现自己一开始就TM的错了,然后又写了N多边,,最后终于AC了
思路 :1第一个说话的人一定不是复读机
2如果说一个人是复读机,那么他,每次说话,都要重复前一个人的话;
3如果说一个人开始重复前一个人的话,看着有点像复读机。但后来没有重复前一个人的话,那么他也不是复读机。
#include<iostream> #include<map> #include<algorithm> #include<string> using namespace std; const int N=10010; struct stu { string a;//保存复读机的名字 int b;//保存复读机的熟练度 // bool friend operator <(const stu &x,const stu &y){ // if(x.b!=y.b) return x.b>y.b; // return x.a<y.a;//内置重载,直接定义排序规则,也可以在外边写一个cmp //} }arr[N]; bool cmp(stu x,stu y){ if(x.b!=y.b) return x.b>y.b; return x.a<y.a; } int main() { int t; cin>>t; while(t--){ map<string,int >mp1,mp2;//判断是否为复读机 mp1用来标记不是复读机的人,mp2用来标记复读机的熟练度 map<string,int>::iterator it; int n; cin>>n; string c[N],d[N]; for(int i=0;i<n;i++){ cin>>c[i]>>d[i]; if(i==0){ mp1[c[i]]=1;//第一个出现的一定不是复读机 } else mp1[c[i]]=0;//复读机标记为0; } int pos=0; for(int i=1;i<n;i++){ if(d[i]==d[i-1]&&mp1[c[i]]!=1){//如果说第i个人重复了前一个人的话,并且不为1那么他就是复读机 mp2[c[i]]++; } else { mp1[c[i]]=1;//不是复读机标记为0; } }
//将复读机的熟练度与名字转换为结构体数组 for(it=mp1.begin();it!=mp1.end();it++){ if(it->second!=1){ arr[pos].a=it->first; arr[pos].b=mp2[it->first]; pos++; } } if(pos==0){ cout<<"Unbelievable!"<<endl; } else { // sort(arr,arr+pos);//如果用内置函数的话用这个排序 sort(arr,arr+pos,cmp); //外置cmp用这个排序 for(int i=0;i<pos;i++){ cout<<arr[i].a<<endl; } } mp1.clear(); mp2.clear(); } return 0; }