Codeforces Round #582 (Div. 3)

打场 CF 不容易呀,加载题目都加载了半天。

太水的题就不放题面了。

A. Chips Moving

输出奇数个数和偶数个数的较小值。

 1 #include<bits/stdc++.h>
 2 #define rep(i,a,b) for(register int i=a;i<=b;++i)
 3 #define rpd(i,a,b) for(register int i=a;i>=b;--i)
 4 #define rep1(i,x) for(register int i=head[x];i;i=nxt[i])
 5 typedef long long ll;
 6 using namespace std;
 7 inline int read(){
 8     int x=0,f=1;char ch=getchar();
 9     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
10     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
11     return x*f;
12 }
13 int n;int a[3];
14 int main(){
15     n=read();rep(i,1,n){int k=read();a[k%2]+=1;}
16     printf("%d
",min(a[0],a[1]));
17     return 0;
18 }
View Code

B. Bad Prices

刚开始 sb 了,套了个树状数组上去,结果 T 了。

其实只要从后往前做并记录最小值就行了。

 1 #include<bits/stdc++.h>
 2 #define rep(i,a,b) for(register int i=a;i<=b;++i)
 3 #define rpd(i,a,b) for(register int i=a;i>=b;--i)
 4 #define rep1(i,x) for(register int i=head[x];i;i=nxt[i])
 5 typedef long long ll;
 6 const int N=150000+5;
 7 using namespace std;
 8 inline int read(){
 9     int x=0,f=1;char ch=getchar();
10     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
11     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 int T;int n,ans,now;int a[N];
15 int main(){
16     T=read();
17     while(T--){
18         n=read();rep(i,1,n)a[i]=read();
19         ans=0;now=a[n];
20         rpd(i,n-1,1){
21             ans+=(a[i]>now);
22             now=min(now,a[i]);
23         }
24         printf("%d
",ans);
25     }
26     return 0;
27 }
View Code

C. Book Reading

求 1 - N 中 M 的倍数的个位数字之和

这个东西是有循环节的,而且循环节不超过 10,所以枚举出循环节就好了。

 1 #include<bits/stdc++.h>
 2 #define rep(i,a,b) for(register int i=a;i<=b;++i)
 3 #define rpd(i,a,b) for(register int i=a;i>=b;--i)
 4 #define rep1(i,x) for(register int i=head[x];i;i=nxt[i])
 5 typedef long long ll;
 6 const int N=100+5;
 7 using namespace std;
 8 inline int read(){
 9     int x=0,f=1;char ch=getchar();
10     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
11     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 int T,t;ll n,m;ll a[N];
15 int main(){
16     T=read();
17     while(T--){
18         cin>>n>>m;memset(a,0,sizeof(a));
19         ll k=m%10LL,kk=k;
20         a[t=1]=kk;(kk+=k)%=10LL;
21         while(kk!=k)a[++t]=kk,(kk+=k)%=10LL;
22         rep(i,2,t)a[i]+=a[i-1];
23         ll div=n/m;
24         printf("%I64d
",(div/(1LL*t))*a[t]+a[(int)(div%(1LL*t))]);
25     }
26     return 0;
27 }
View Code

D2. Equalizing by Division (hard version)

给你 N 个数,一次操作可以把一个数 x 变成 x/2 (向下取整)。

求最少操作得到 M 个相同的数。

刚开始想到 bfs 标号的完全二叉树,一次操作就是跳向它的父结点。

所以可以把每个数都跳到 1,沿途记下每个点能到达它的数字个数和操作数。

因为是求最少操作,所以从小到大做就行了。

 1 #include<bits/stdc++.h>
 2 #define rep(i,a,b) for(register int i=a;i<=b;++i)
 3 #define rpd(i,a,b) for(register int i=a;i>=b;--i)
 4 #define rep1(i,x) for(register int i=head[x];i;i=nxt[i])
 5 typedef long long ll;
 6 const int N=2e5+5;
 7 using namespace std;
 8 inline int read(){
 9     int x=0,f=1;char ch=getchar();
10     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
11     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 int n,k;int a[N];ll ans=1e18;ll v[N],s[N];
15 int main(){
16     n=read();k=read();
17     rep(i,1,n)a[i]=read();sort(a+1,a+n+1);
18     rep(i,1,n){
19         int t=a[i];ll now=0;
20         while(t){
21             s[t]+=1;v[t]+=now;now+=1LL;
22             if(s[t]==k)ans=min(ans,v[t]);
23             t/=2;
24         }
25     }
26     printf("%I64d
",ans);
27     return 0;
28 }
View Code

E. Two Small Strings

给两个长度为 2 且只包含 a b c 的串,求一个长度为 3n 的串满足有 n 个 a,n 个 b,n 个 c且所给的串不是它的子串。

这道题是真的烦,细节很多,考场上没想完全,其实就是分类讨论。

 1 #include<bits/stdc++.h>
 2 #define rep(i,a,b) for(register int i=a;i<=b;++i)
 3 #define rpd(i,a,b) for(register int i=a;i>=b;--i)
 4 #define rep1(i,x) for(register int i=head[x];i;i=nxt[i])
 5 typedef long long ll;
 6 using namespace std;
 7 inline int read(){
 8     int x=0,f=1;char ch=getchar();
 9     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
10     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
11     return x*f;
12 }
13 int n;string s1,s2,s;
14 int main(){
15     n=read();cin>>s1>>s2;
16     if(s1=="aa"||s1=="bb"||s1=="cc"){
17         if(s2=="aa"||s2=="ac"||s2=="ba"||s2=="bb"||s2=="cb"||s2=="cc")s="abc";
18         if(s2=="ab"||s2=="bc"||s2=="ca")s="acb";
19         puts("YES");rep(i,1,n)cout<<s;
20         return 0;
21     }
22     swap(s1,s2);
23     if(s1=="aa"||s1=="bb"||s1=="cc"){
24         if(s2=="aa"||s2=="ac"||s2=="ba"||s2=="bb"||s2=="cb"||s2=="cc")s="abc";
25         if(s2=="ab"||s2=="bc"||s2=="ca")s="acb";
26         puts("YES");rep(i,1,n)cout<<s;
27         return 0;
28     }
29     rep(i,1,3){
30         rep(j,1,3){
31             rep(k,1,3){
32                 if(i==j||i==k||j==k)continue;
33                 s="";
34                 s=s+(char)(i+96);
35                 s=s+(char)(j+96);
36                 s=s+(char)(k+96);
37                 bool f=0;
38                 rep(t,0,1)if(s[t]==s1[0]&&s[t+1]==s1[1]){f=1;break;}
39                 if(f)continue;
40                 rep(t,0,1)if(s[t]==s2[0]&&s[t+1]==s2[1]){f=1;break;}
41                 if(f)continue;
42                 puts("YES");
43                 rep(i,1,n)cout<<s[0];
44                 rep(i,1,n)cout<<s[1];
45                 rep(i,1,n)cout<<s[2];
46                 return 0;
47             }
48         }
49     }
50     return 0;
51 }
View Code

G. Path Queries

给一棵边有权的树,多次询问求有几个点对满足从一个点到另一个点的简单路径上的边权最大值不超过 Qi 。

离线处理,考虑把边一条一条加进去,

如果把 u 所在的树和 v 所在的树合并,答案增加的数量为 size* sizev .

 1 #include<bits/stdc++.h>
 2 #define rep(i,a,b) for(register int i=a;i<=b;++i)
 3 #define rpd(i,a,b) for(register int i=a;i>=b;--i)
 4 #define rep1(i,x) for(register int i=head[x];i;i=nxt[i])
 5 typedef long long ll;
 6 const int N=2e5+5;
 7 using namespace std;
 8 inline int read(){
 9     int x=0,f=1;char ch=getchar();
10     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
11     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 struct edge{int x,y,z;}e[N];
15 bool cmp1(edge i,edge j){return i.z<j.z;}
16 struct Query{int x,id;}q[N];
17 bool cmp2(Query i,Query j){return i.x<j.x;}
18 int n,m;int f[N],h[N];ll now,ans[N];
19 int get(int x){return f[x]==x?x:f[x]=get(f[x]);}
20 int main(){
21     n=read();m=read();
22     rep(i,1,n-1)e[i].x=read(),e[i].y=read(),e[i].z=read();
23     rep(i,1,m)q[i].x=read(),q[i].id=i;
24     sort(e+1,e+n,cmp1);sort(q+1,q+m+1,cmp2);
25     int l=0;rep(i,1,n)f[i]=i,h[i]=1;
26     rep(i,1,m){
27         while(l<n-1&&e[l+1].z<=q[i].x){
28             l+=1;int xx=get(e[l].x),yy=get(e[l].y);
29             if(xx==yy)continue;
30             now+=1LL*h[xx]*h[yy];
31             h[xx]+=h[yy];f[yy]=xx;
32         }
33         ans[q[i].id]=now;
34     }
35     rep(i,1,m)printf("%I64d ",ans[i]);
36     return 0;
37 }
View Code

F 题考场上没时间做。

原文地址:https://www.cnblogs.com/maximumhanyu/p/11447376.html