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;

•代码

#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,则自身结合,这样是使用三个数

•代码

#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;

•代码

#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;
}

原文地址:https://www.cnblogs.com/MMMinoz/p/11073577.html

时间: 2024-10-11 19:30:00

Codeforces Round #565 (Div. 3)的相关文章

Codeforces Round #565 (Div. 3) C. Lose it!

链接: https://codeforces.com/contest/1176/problem/C 题意: You are given an array a consisting of n integers. Each ai is one of the six following numbers: 4,8,15,16,23,42. Your task is to remove the minimum number of elements to make this array good. An a

Codeforces Round #565 (Div. 3) B

B. Merge it! 题目链接:http://codeforces.com/contest/1176/problem/B 题目 You are given an array a consisting of n integers a1,a2,…,an In one operation you can choose two elements of the array and replace them with the element equal to their sum (it does not

Codeforces Round #565 (Div. 3) A

A. Divide it! 题目链接:http://codeforces.com/contest/1176/problem/A 题目 You are given an integer n You can perform any of the following operations with this number an arbitrary (possibly, zero) number of times: Replace n with n2 if n is divisible by 2;Rep

Codeforces Round #565 (Div. 3) E. Cover it!

题目:https://codeforces.com/contest/1176/problem/E 思路:奇偶染色 #include<bits/stdc++.h> using namespace std; #define DEBUG cout<<"DEBUG"<<endl typedef long long ll; typedef unsigned long long ull; typedef pair<int,int>pii; typed

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除