Codeforces Round #514 (Div. 2) C. Sequence Transformation

博客围绕数字删除以改变最大公约数(gcd)展开。先阐述相邻数gcd为1,需删奇数使gcd不为1,再通过不断除以gcd重复操作。但对于第一组样例发现原算法非最优,指出n>=4符合规律,n=3时需特殊判断,先删1、2再删3可使最后数变大。

http://codeforces.com/contest/1059/problem/C

首先,我们得知道一个事情两个系那个相邻的数的gcd一定是1,根据更相减损术gcd(x,x+1)=gcd(x,1)=1

所以首先要删掉一些数字使得gcd不是1,那么就是删掉所有奇数,。

如1 2 3 4 5 6 7 8

删去奇数为 2 4 6 8 ,此时gcd=2;

要想使gcd删除最少的数再次变大先全部除以2得1 2 3 4

又回到了最初的问题,删去奇数得2 4 此时gcd=4,除以gcd

得1 2,删去奇数得2 结果就是1 1 1 1 2 2 4 8

此时思路大概已经出来了,但是对于第一组样例

3

1 1 3

如果走上边得算法会得到1 1 2并不是最优解

但是n>=4就符合规律,所以3要特殊判断当剩下三个数就是1 2 3 的时候一定要先删去1 2 再删除3这样最后一个数就变大了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN=1000005;
int ans[MAXN];
int main()
{
    int n;
    cin>>n;
    int l=0;
    int now=1;
    while(n)
    {
        if(n==3){
            ans[++l]=now,ans[++l]=now;ans[++l]=now*3;break;
        }
        int num=n-n/2;
        for(int i=1;i<=num;i++){
            ans[++l]=now;
        }
        n-=num;
        now*=2;
    }
    for(int i=1;i<=l;i++){
        cout<<ans[i]<<" ";
    }
    cout<<endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值