codeforces 771 (VK Cup 2017 - Round 1)
作者:互联网
A. Bear and Friendship Condition
•题意
给你n个人,m个朋友关系
朋友是会传递的,若A B是朋友,A C是朋友,则必须有B C的朋友关系
符合这个关系输出YES,否则输出NO
•思路
n个人,但凡是有朋友关系的,必定在同一个朋友圈内
所以可以分成若干个朋友圈
在一个朋友圈内部,若符合条件肯定是互为朋友
也就是 是一个完全图
接下来就是判断是否是完全图了
举个栗子:1234在一个朋友圈内,且符合条件
则人与朋友的对应关系为
1与1 2 3 4为朋友
2与1 2 3 4为朋友
3与1 2 3 4为朋友
4与1 2 3 4为朋友
即,他们的朋友是完全相同的!
挨个去判断朋友是否相同显然时间复杂度不够优雅
只需要排序后,看第一个朋友是否相等就可以
O(n)变O(1)!
为什么呢? 因为每个人的朋友圈都要去查看一遍,如果A的朋友圈没有B,但是B的朋友圈有A
那么,B和A的朋友圈肯定对不上,所以就输出NO了
•代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=2e5+5; 5 vector<int> a[maxn]; 6 //我加vis数组是为了减少不必要的查看来减少时间 7 //氮素 貌似效率还不如不加vis的,搞不懂 ??? 8 bool vis[maxn]; 9 10 int main() 11 { 12 // freopen("C:\\Users\\14685\\Desktop\\C++workspace\\in&out\\contest","r",stdin); 13 int n,m; 14 cin>>n>>m; 15 for(int i=1;i<=m;i++) 16 { 17 int x,y; 18 cin>>x>>y; 19 a[x].push_back(y); 20 a[y].push_back(x); 21 } 22 ///把自己也加进自己的朋友圈 23 for(int i=1;i<=n;i++) 24 a[i].push_back(i); 25 ///排序 26 for(int i=1;i<=n;i++) 27 sort(a[i].begin(),a[i].end()); 28 29 ///查看每个人的朋友圈 30 for(int i=1;i<=n;i++) 31 { 32 if(vis[i]) 33 continue; 34 ///自己的朋友圈和朋友的朋友圈对比 35 for(int j=0;j<a[i].size();j++) 36 { 37 if(a[i].size()==a[a[i][j]].size()) 38 { 39 vis[a[i][j]]=true; 40 ///朋友圈不相同 41 if(a[i][0]!=a[a[i][j]][0]) 42 { 43 puts("NO"); 44 return 0; 45 } 46 } 47 else 48 { 49 puts("NO"); 50 return 0; 51 } 52 } 53 } 54 puts("YES"); 55 }View Code
B - Bear and Different Names
•题意
有n个人,从1个人开始每k个一组
[1,k] [2,k+1]....
如果有重名的则NO,否则YES
根据NO和YES的结果输出名字
名字首字母大写,且1<=名字长度<=10
•思路
因为名字长度有限制,可能有很多人名字不同
所以首先预处理出不同名字来,注意计算名字个数
(这里踩了坑)
首先找到第一个YES为切入点,后边的名字可以由他得到
已经确定了的名字不能再更改!否则会引起与前面的YES/NO不符 (这里也踩了坑
如果是YES的话就选择新名字,否则选择和这k个人的第一个人相同的名字(也就是首尾名字重合
然后再找第一个YES前面的人,从第一个YES开始倒找,让他前面的都和他重名
•代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=2e5+5; 5 string name[55],nname[3000]; 6 string s[55]; 7 int wh[10]; 8 ///预处理名字 9 void Init() 10 { 11 for(int i=0;i < 10;++i) 12 wh[i]=i; 13 int cnt=0; 14 do 15 { 16 for(int i=0;i<10;i++) 17 { 18 if(i==0) 19 nname[++cnt]=wh[0]+'A'; 20 else 21 nname[cnt]+=(wh[i]+'a'); 22 } 23 if(cnt>2500) 24 return ; 25 }while(next_permutation(wh,wh+10)); 26 } 27 int main() 28 { 29 // freopen("C:\\Users\\14685\\Desktop\\C++workspace\\in&out\\contest","r",stdin); 30 int n,m; 31 cin>>n>>m; 32 bool flag=false; 33 Init(); 34 int cut=0; 35 for(int i=1;i<=n-m+1;i++) 36 { 37 cin>>s[i]; 38 if(s[i]=="YES") 39 { 40 flag=true; 41 for(int j=i;j<=i+m-1;j++) 42 if(name[j].empty()) 43 name[j]=nname[++cut];///选择新名字 44 } 45 else///这k个人首尾名字重合 46 name[i+m-1]=name[i]; 47 } 48 49 if(!flag) 50 for(int i=1;i<=n;i++) 51 cout<<"Aa"<<' '; 52 else 53 { 54 ///找第一个YES 55 int index; 56 for(index=1;index<=n-m+1;index++) 57 if(s[index]=="YES") 58 break; 59 ///前面的人和他重名 60 for(int i=index;i>=0;i--) 61 name[i]=name[index]; 62 63 for(int i=1;i<=n;i++) 64 cout<<name[i]<<' '; 65 } 66 }View Code
标签:771,Cup,int,VK,朋友,名字,朋友圈,NO,YES 来源: https://www.cnblogs.com/MMMinoz/p/11561321.html