ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

codeforces 771 (VK Cup 2017 - Round 1)

2019-09-21 09:04:30  阅读:350  来源: 互联网

标签:771 Cup int VK 朋友 名字 朋友圈 NO YES


传送门

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有