Codeforces Round #544 (Div. 3)

A. Middle of the Contest

题意:给出起始和结束时间找出中间时间 而且都是偶数

思路:全部转成分钟加起来然后除2再转成时间即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
 4 #define MT(x,i) memset(x,i,sizeof(x))
 5 #define inf 0x3f3f3f3f
 6 #define mkp make_pair
 7 #define all(v) (v).begin(),(v).end()
 8 #define F first
 9 #define S second
10 #define pii pair<int,int>
11 #define pb push_back
12 const int maxn=5e5+5;
13 char s[maxn],t[maxn];
14 void get_next(char*x,int len,char*next){
15     int i,j;
16     j=next[0]=-1;
17     i=0;
18     while(i<len){
19         while(-1!=j&&x[i]!=x[j])j=next[j];
20         next[++i]=++j;
21     }
22 }
23 
24 int main(){
25     int h1,h2,m1,m2;
26     scanf("%d:%d%d:%d",&h1,&m1,&h2,&m2);
27     int sum=(h1+h2)*60+m1+m2;
28     sum/=2;
29     printf("%02d:%02d\n",sum/60,sum%60);
30     return 0;
31 }

 

B. Preparation for International Women's Day

题意:给出一组数组和一个k 问两两组合 可以最多组成多少个k的倍数的数字 

思路:直接%k然后组合就行

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
 4 #define MT(x,i) memset(x,i,sizeof(x))
 5 #define inf 0x3f3f3f3f
 6 #define mkp make_pair
 7 #define all(v) (v).begin(),(v).end()
 8 #define F first
 9 #define S second
10 #define pii pair<int,int>
11 #define pb push_back
12 const int maxn=5e5+5;
13 int a[maxn];
14 void get_next(char*x,int len,char*next){
15     int i,j;
16     j=next[0]=-1;
17     i=0;
18     while(i<len){
19         while(-1!=j&&x[i]!=x[j])j=next[j];
20         next[++i]=++j;
21     }
22 }
23 map<int ,int >mp;
24 int main(){
25     int n,k;
26     scanf("%d%d",&n,&k);
27     for(int i=0;i<n;i++)scanf("%d",&a[i]),mp[a[i]%k]++;
28     int ans=0;
29     for(int i=1;i<k;i++){
30         if(i!=k-i){
31             int tmp=min(mp[i],mp[k-i]);
32             mp[i]-=tmp,mp[k-i]-=tmp;
33             ans+=tmp;
34         }
35         else {
36             ans+=mp[i]/2;
37             mp[i]-=mp[i]/2;
38         }
39 //        cout<<i<<" "<<ans<<endl;
40     }
41     ans+=mp[0]/2;
42     cout<<ans*2<<endl;
43     return 0;
44 }

C. Balanced Team

题意 给出一组数 问最长的 一个子序列 的长度:其中的元素差距小于等于5

思路 :直接双指针滑动窗口扫过去即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
 4 #define MT(x,i) memset(x,i,sizeof(x))
 5 #define inf 0x3f3f3f3f
 6 #define mkp make_pair
 7 #define all(v) (v).begin(),(v).end()
 8 #define F first
 9 #define S second
10 #define pii pair<int,int>
11 #define pb push_back
12 const int maxn=5e5+5;
13 int a[maxn];
14 int main(){
15     int n;
16     scanf("%d",&n);
17     FOR(i,0,n-1)scanf("%d",&a[i]);
18     sort(a,a+n);
19     int p1=0,p2=1;
20     int ans=1;
21     for(;;){
22     
23         while(p2<n&&a[p2]-a[p1]<=5)p2++;
24         ans=max(ans,p2-p1);
25         p1++;
26         if(p2>=n)break;
27     }
28     cout<<ans<<endl;
29 
30     return 0;
31 }

D. Zero Quantity Maximization

题意:c=da+b 给出  a 和b 可以任意选择一个实数d使得da+b=0  其中对同一个d使c越多越好

思路:判断一下 恒等于0 和除数为0等情况 还有注意精度问题  这里用double被卡用Long double 过了  如果long double 还不过可以用分数形式过 开个pair每次gcd一下即可 正负可以标在pair的制定标准位上 即第一位和第二位都可以

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
 4 #define MT(x,i) memset(x,i,sizeof(x))
 5 #define inf 0x3f3f3f3f
 6 #define mkp make_pair
 7 #define all(v) (v).begin(),(v).end()
 8 #define F first
 9 #define S second
10 #define pii pair<int,int>
11 #define pb push_back
12 const int maxn=5e5+5;
13 int a[maxn],b[maxn];
14 set<long double>q;
15 const long double eps=1.0;
16 map<long double ,int>mp;
17 int main(){
18     int n;
19     scanf("%d",&n);
20     FOR(i,0,n-1)scanf("%d",&a[i]);
21     FOR(i,0,n-1)scanf("%d",&b[i]);
22     int ans=0;
23     FOR(i,0,n-1){
24         if(b[i]==0){
25             if(a[i]==0)ans++;
26             else mp[0]++,q.insert(0);
27         }
28         else {
29             if(a[i]==0)continue;
30             else {
31                 mp[-b[i]*1.0/a[i]]++;
32                 q.insert(-b[i]*eps/a[i]);
33             }
34         }
35     }
36     int maxnum=0;
37     for(auto it:q){
38         maxnum=max(mp[it],maxnum);
39     }
40     cout<<maxnum+ans<<endl;
41     return 0;
42 }
E. K Balanced Teams
思路 :上面的题的加强版 找出k组数 每组数内部的差距不超过5 使得这k组人的总数最大
思路:dp[i][j] 前i个人组成j组最大有多少个人   预处理当前i可以和后面几个人组成一组
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
 4 #define MT(x,i) memset(x,i,sizeof(x))
 5 #define inf 0x3f3f3f40
 6 #define mkp make_pair
 7 #define all(v) (v).begin(),(v).end()
 8 #define F first
 9 #define S second
10 #define pii pair<int,int>
11 #define pb push_back
12 #define all(v) v.begin(),v.end()
13 
14 
15 int main(){
16 int n,k;
17 scanf("%d%d",&n,&k);
18 vector<int>a(n);
19 vector<int>cnt(n);
20 FOR(i,0,n-1)cin>>a[i];
21 sort(all(a));
22 FOR(i,0,n-1){
23     while(i+cnt[i]<n&&a[i+cnt[i]]-a[i]<=5)cnt[i]++;
24 }
25 vector<vector<int> >dp(n+1,vector<int>(k+1));
26 FOR(i,0,n-1){
27     FOR(j,0,k){
28         dp[i+1][j]=max(dp[i+1][j],dp[i][j]);
29         if(j+1<=k){
30             dp[i+cnt[i]][j+1]=max(dp[i+cnt[i]][j+1],dp[i][j]+cnt[i]);
31         }
32     }
33 }
34 cout<<dp[n][k]<<endl;
35 return 0;
36 }

F1. Spanning Tree with Maximum Degree

题意:给出一个联通无向无权图 没有自环 平行边  树的最大度数的点的度数为树的度数 让你构造一个生成树 使得 生成树的度数最大

思路:直接记下最大度数的顶点 然后并查集连一下和其直接相连的边 然后找没有和最大顶点联通的点 连上即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
 4 #define MT(x,i) memset(x,i,sizeof(x))
 5 #define inf 0x3f3f3f3f
 6 #define mkp make_pair
 7 #define all(v) (v).begin(),(v).end()
 8 #define F first
 9 #define S second
10 #define pii pair<int,int>
11 #define pb push_back
12 const int maxn=2e6+5;
13 
14 struct Node{
15     int next,to;
16 }edge[maxn+5];
17 int head[maxn];
18 int dgree[maxn+5];
19 int size=0;
20 void add(int x,int y){
21     edge[size].to=y;
22     edge[size].next=head[x];
23     head[x]=size++;
24     edge[size].to=x;
25     edge[size].next=head[y];
26     head[y]=size++;
27     dgree[x]++;
28     dgree[y]++;
29 }
30 int father[maxn];
31 int find(int x){
32     return x==father[x]?x:father[x]=find(father[x]);
33 }
34 void merge(int x,int y){
35     x=find(x),y=find(y);
36     if(x!=y)father[x]=y;
37 }
38 int main(){
39     int n,m;
40     scanf("%d%d",&n,&m);
41     FOR(i,0,n)father[i]=i;
42     int maxnum=-1,id;
43     memset(head,-1,sizeof(head));
44     for(int i=0;i<m;i++){
45         int x,y;
46         scanf("%d%d",&x,&y);
47         add(x,y);
48         if(maxnum<dgree[x]){
49             maxnum=dgree[x];
50             id=x;
51         }
52         if(maxnum<dgree[y]){
53             maxnum=dgree[y];
54             id=y;
55         }
56     }
57     for(int i=head[id];i!=-1;i=edge[i].next){
58         printf("%d %d\n",id,edge[i].to);
59         merge(id,edge[i].to);
60     }
61     for(int i=1;i<=n;i++){
62         if(find(id)!=find(i)){
63             for(int j=head[i];j!=-1;j=edge[j].next){
64                 if(find(i)!=find(id)&&find(edge[j].to)==find(id)){
65                     printf("%d %d\n",edge[j].to,i);
66             //        cout<<find(edge[j].to)<<" 23zz3 "<<find(id)<<endl;
67                     merge(i,id);
68 
69                 }
70                 if(find(edge[j].to)!=find(i)&&find(edge[j].to)!=find(id))
71                 {
72                     printf("%d %d\n",edge[j].to,i);
73             //        cout<<find(edge[j].to)<<" 233  "<<find(i)<<endl;    
74                     merge(edge[j].to,i);
75                 }
76             }
77         }
78     }
79     return 0;
80 }
F2. Spanning Tree with One Fixed Degree
题意:和上题类似 除了多个一个d d指的是 构造的生成树要满足1的度数要为d 所以这样就可能联通不了要判是否能够构成
思路:先看除了1有几个联通快  要是联通快的快数>1的度数 那肯定是连不上的  如果可以构造 那么先构造每个联通快和1连一条边(这里如果不按照每个联通块都连一条边的顺序去连会WA 37 这里给出一组自己构造的HACK数据:
7 7 2
1 2
1 3
2 3
1 4
4 5
4 7
4 6
这里会被hack就是因为1直接和处于同一联通快的 2 3相连了 没有多余的度来连接另外一块联通快
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
  4 #define MT(x,i) memset(x,i,sizeof(x))
  5 #define inf 0x3f3f3f40
  6 #define mkp make_pair
  7 #define all(v) (v).begin(),(v).end()
  8 #define F first
  9 #define S second
 10 #define pii pair<int,int>
 11 #define pb push_back
 12 const int maxn =2e6+5;
 13 #define MS(shuzhu,zhi)  memset(shuzhu,zhi,sizeof(shuzhu))
 14 int size=0;
 15 struct Node{
 16 int to,next;
 17 }edge[maxn*4];
 18 int dgree[maxn];
 19 int father[maxn];
 20 int head[maxn];
 21 void add(int x,int y){
 22     edge[size].to=y;
 23     edge[size].next=head[x];
 24     head[x]=size++;
 25     dgree[x]++;
 26 }
 27 vector<pii>v;
 28 int find(int x){
 29 return x==father[x]?x:father[x]=find(father[x]);
 30 }
 31 void merge(int x,int y){
 32 x=find(x),y=find(y);
 33 if(x!=y)father[x]=y;
 34 }
 35 int vis[maxn];
 36 int used[maxn];
 37 void dfs(int x,int value){
 38     vis[x]=value;
 39     for(int i=head[x];i!=-1;i=edge[i].next){
 40         int u=edge[i].to;
 41         if(!vis[u]&&u!=1)dfs(u,value);
 42     }
 43 }
 44 int main(){
 45     int n,m,d;
 46      size=0;
 47     memset(head,-1,sizeof(head));
 48     scanf("%d%d%d",&n,&m,&d);
 49     FOR(i,0,n)father[i]=i;
 50     for(int i=0;i<m;i++){
 51         int x,y;
 52         scanf("%d%d",&x,&y);
 53         add(x,y),add(y,x);
 54     }
 55     int tmp=0;
 56     int cnt=1;
 57     for(int i=2;i<=n;i++){
 58         if(!vis[i])dfs(i,cnt++);    
 59     }
 60     //cout<<" "<<cnt<<endl; 
 61     if(tmp>d||dgree[1]<d||(d<cnt-1)){
 62         printf("NO\n");
 63         return 0;
 64     }
 65     printf("YES\n");
 66     int num=0;
 67 for(int i=head[1];i!=-1;i=edge[i].next){
 68         int u=edge[i].to;
 69         if(!used[vis[u]]){
 70         printf("%d %d\n",1,u);
 71          merge(1,u);
 72          used[vis[u]]=1;
 73          num++;
 74             if(num>=d)break;     
 75         }
 76         
 77 }
 78     if(num<d)
 79 for(int i=head[1];i!=-1;i=edge[i].next){
 80         int u=edge[i].to;
 81         if(find(u)!=find(1)){
 82             num++;
 83         printf("%d %d\n",1,u);
 84             merge(1,u);
 85             if(num>=d)break;
 86         }
 87     }
 88 
 89     FOR(i,2,n){
 90         if(find(i)!=find(1)){
 91             for(int j=head[i];j!=-1;j=edge[j].next){
 92                 int u=edge[j].to;
 93                 if(find(u)!=find(i)&&u!=1){
 94                     printf("%d %d\n",u,i);
 95                     merge(u,i);
 96                 }
 97             }
 98         }
 99     }
100 return 0;
101     
102 }

 

posted @ 2019-03-17 14:17  tttttttttrx  阅读(161)  评论(0编辑  收藏  举报