Codeforces Round #565 (Div. 3)
Posted mmminoz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #565 (Div. 3)相关的知识,希望对你有一定的参考价值。
A. Divide it!
•题意
给定一个数n, 每次可以进行下列一种操作
1.如果n可以被2整除,用n/2代替n
2.如果n可以被3整除,用2n/3代替n
3.如果n可以被5整除,用4n/5代替n
如果可以经过上述操作使得 n 变为 1,输出最小操作次数,反之,输出-1;
•思路
n/2 < 2n/3 < 4n/5 要想操作次数最少,优先操作 1 > 2 > 3;
•代码
View Code#include<bits/stdc++.h> using namespace std; #define ll long long int a[105]; int main() int t; cin>>t; while(t--) ll n; cin>>n; int flag=0; int Count=0; while(n>1) if(n%2==0)//1 n/=2; Count++; else if(n%3==0)//2 n=n/3*2; Count++; else if(n%5==0)//3 n=n/5*4; Count++; else//不能被整除,即经过操作不能变为1 flag=1; break; if(flag) cout<<-1<<endl; else cout<<Count<<endl;
B. Merge it!
•题意
给你一个包含 n 个数的序列 a;
定义序列 a 上的一个操作:合并任意两个元素;
你可以对序列 a 执行上述操作任意次,求操作后的序列最多有多少元素可以被 3 整除;
•思路
对于任意一个数x
1.如果x是3的倍数,x%3==0
如果x不是3的倍数
2.如果x+1是3的倍数,x%3==1,3*x%x==0
3.如果x+2是3的倍数,x%3==2,3*x%x==0
如果想尽可能多的是三的倍数:
首先加x%3==0的x的个数,这样只使用一个数
其次2和3相加正好是3的倍数,这样只使用两个数
最后还剩下2或者3,则自身结合,这样是使用三个数
•代码
View Code#include<bits/stdc++.h> using namespace std; int a[105]; int main() int t; cin>>t; while(t--) int n; cin>>n; int zero=0,one=0,two=0;//分别记录x%3为0,1,2的个数 for(int i=0;i<n;i++) cin>>a[i]; a[i]%=3; if(a[i]==0) zero++; else if(a[i]==1) one++; else two++; // cout<<zero<<‘ ‘<<one<<‘ ‘<<two<<endl; if(one>=two) cout<<zero+two+(one-two)/3<<endl; else cout<<zero+one+(two-one)/3<<endl;
C. Lose it!
•题意
给你一个包含 n 个整数的序列 a和good序列4,8,15,16,23,42;
在删去 x 个数后,使得序列 a 可以划分成 (n-x) / 6 个 "good" 序列;
求 x 的最小值;
•题解
求出序列 a 最多有多少个 "good" 序列(假设有 ans 个),需要删去的个数就是 n-6×ans;
•代码
View Code#include<bits/stdc++.h> using namespace std; const int maxn=500005; vector<int> p[43]; int s[maxn]; int t[]=0,4,8,15,16,23,42; int ans=0;//一共有ans个good串 int a[50];//记录使用后的每个字母的最后一个位置,即这个字母到达的最远的位置 //后面再找这个字母时,从这个位置的下一个开始找,可以减少查找量 int main() int n; cin>>n; for(int i=1;i<=n;i++) cin>>s[i]; p[s[i]].push_back(i);//预处理s串每个good数的位置 int cur=0; int flag; for(int i=1;i<=6;i++) flag=0; for(int j=a[t[i]];j<p[t[i]].size();j++) flag=0; if(p[t[i]][j]>cur)//在s串中找x出现的位置 >cur 的第一个位置,有点贪心的感jio cur=p[t[i]][j];//更新cur a[t[i]]=j+1;//记录之前x到达的最远位置j,后面从j+1开始找 flag=1; break; if(!flag) break; if(cur>n) break; if(i==6)//找完一次,再从第一个good数找下一次 ans++; cur=0; i=0; cout<<n-ans*6<<endl;
以上是关于Codeforces Round #565 (Div. 3)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #565 (Div. 3) C. Lose it!
Codeforces Round #565 (Div. 3)
Codeforces Round #565 (Div. 3) E. Cover it!
Codeforces Round #565 (Div. 3)