5.5日的CF刷题总结~【标签: constructive algorithms难度: 1300~ 1500】

 

前天一气写了十个题的题解, 可吐了,但是复盘有必要

 

所以!晚上听着歌把一天的题总结下吧~

 

说实话,个人观点,今天做的题感觉比前几天难了点,但是cf官方给出的难度还是1300-1500

 

今日战绩

前两个都浅浅搜了下,最后一个看过基础课数学部分应该就能想出来

 

 

B. Find The Array

 

Problem - 1463B - Codeforces  难度:1400, 类型:二进制,思维

 

题意

给了数组a, 要构造出数组b,使得数组b里面相邻两数可以一项整除另一项,即b[i-1]整除b[i]  或   b[i]整除a[i-1], 并且

 

 

 题解

 

1可以与任意正数有整除关系,所以我们以此为入手点

分别计算奇数位和偶数位之和,数之和最小的位都变成1,其他的和数组a一样

 

看代码

 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;

const int N = 2e5+10;

int a[60], b[60], n;
LL summ=0;

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
        LL odd = 0, even = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++)
            scanf("%d", &a[i]), i&1==1? odd+=a[i]: even+=a[i];
            
        if(odd<=even)
            for(int i = 1; i<= n; i ++)
                if(i%2==0) cout << a[i] << ' ' ;
                else    cout << "1 ";
        
        elsefor(int i = 1; i<= n; i ++)
                if(i&1==1) cout << a[i] << ' ' ;
                else    cout << "1 ";
           
        cout <<endl;
    }
    return 0;
}

 

 

 



 

 

B. Suffix Operations

 

Problem - 1453B - Codeforces  难度:1400, 类型:没啥类型  implementation

 

题意

 

用尽量少的次数把n个数变成相等的数,首先有一次额外机会把任意一个数变成任意一个数(也可以不用),然后每次操作可以使后缀数都+1或-1

n:[2,2e5]    ai:[-5e8,  5e8]

 

分析

 

写了一半睡了一觉醒来忘干净了,

为了让所有数一样,我们一定是从后面开始操作,后x个数相等后,让后x个数去等于后x+1个数......, 也就是让所有的数都等于a[1]

如果没有额外机会,abs(a[i]-a[i-1])之和便是答案了,由此发现每个数之于前后两个数有关,那么额外机会减去前后数的影响就行了 - max(abs(a[i]-a[i-1])+ abs(a[i+1]-a[i])-abs(a[i+1]-a[i-1]))

 

代码来了

 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;

const int N = 2e5+10;
LL a[N];

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
        int n;
        LL maxx = 0, sum=0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++) scanf("%lld", &a[i]);
        
        maxx = max(abs(a[2]-a[1]), abs(a[n]-a[n-1]));
        for(int i = 2; i <= n; i ++)
        {
            sum += abs(a[i]-a[i-1]);
            if(i!=n)
            maxx = max(maxx, abs(a[i]-a[i-1])+ abs(a[i+1]-a[i])-abs(a[i+1]-a[i-1]));
        }
        
        cout << sum-maxx<<endl;
    }
    return 0;
}

 

 



 

 

D. Number into Sequence

 

Problem - 1454D - Codeforces 难度:1300,类型:数学,质数

 

题意

给出数组和,要构造出数组,使得a[i+1]可以整除a[i],输出数组个数和数组各元素  t : [1,5000]  n : [ 2,1e10],n的和不超过1e10

分析

就是看n个数最多的质因子了,设times为该质因子出现次数,num为这个质因子,输出times-1个num, 和一个n/pow(k,times-1), 记得转为long long

 
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;

const int N = 1e6+10;
LL primes[N];
bool st[N];
int idx= 0;

void prim()
{
    for(int i = 2; i < N; i ++)
    {
        if(!st[i])    primes[idx++] = i;
        for(int j = 0; primes[j]*i<N ; j ++)
        {
            st[primes[j]*i] = 1;
            if(i % primes[j]==0)break;
        }
    }
}

int main()
{
    prim();
    
    int t;
    scanf("%d", &t);
    while(t --)
    {
        LL n;
        cin >> n;
        int times = 1, num = -1;
        for(int i = 2; i <= n/i; i ++)
        {
            if(i>= N || st[i])continue;
            if(n%i==0)
            {
                int timess = 0;
                for(int j = 1; ; j ++)
                {
                    if(n%(LL)pow(i,j)==0)    timess++;
                    else break; 
                }
                if(timess>times)
                {
                    num = i;
                    times=timess;
                }
            }
        }
        if(num == -1)
        {
            cout << 1<< '\n' << n << '\n';
            continue;
        }
        cout << times << '\n';
        for(int i = 1; i < times; i ++)cout << num <<  ' ';
        cout << n/(LL)pow(num,times-1)<<endl;
    }
    return 0;
}

 

posted @ 2022-05-05 21:59  la-la-wanf  阅读(60)  评论(0编辑  收藏  举报