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

传送门:http://codeforces.com/contest/1059/problem/C

这个c题还挺有意思的,一开始实在是看不懂题,后来理解了,要字典序(误)最大,就必须越快增加整个数列的gcd越好。

注意到这个数列是有序而且从1到n,那么先假设n比较大,这个时候gcd是1,我们要删掉最少的数让gcd改变,最少删掉多少呢?

n范围内,是2这个数的倍数的数的个数,永远比是其他数的倍数的数的个数多,那么我们就要让这个gcd优先变成2,也就意味着我们要删掉所有的奇数,剩下的都是偶数,那么我们发现又要让gcd最快变化,我们就要让gcd变成4,就把所有不是4倍数的删去,然后是8,然后是16 。。。 类推。

那么删到最后,我们会发现,剩下的数字要么是3个,要么是两个,如果剩下两个数,我们假设当前gcd = a,那么我们剩下的两个数就是 a,2*a, 那么如果剩下三个数 那就是 a , 2a, 3a 我们发现对于两个的我们还是像上述的那样把不是gcd*2的倍数的数删掉,最后可以让gcd*2,但是对于剩下三个数的情况,我们如果还是这样删掉的话,2次删除过后,gcd增加到了2*gcd,但是我们如果把前两个数删掉的话,gcd增加到了3*gcd,那么这个情况的字典序肯定是比之前的那种要大,那么我们就对剩下3个数的时候特判即可。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int gcd(int a,int b){if (b == 0) return a; return gcd(b , a%b);}
int lcm(int a, int b){ return a/gcd(a,b)*b;}
inline int read(){
    int f = 1, x = 0;char ch = getchar();
    while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();}
    while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
int main(){
    int n,cnt1,cnt2,now = 1,temp;
    cin >> n; temp = n;
    while(n > 0){
        if (n == 3) {
            printf("%d %d %d\n",now,now,now*3);
            break;
        }
        if (n & 1) {cnt1 = n/2+1; cnt2 = n/2;}
        else cnt1 = cnt2 = n/2;
        while(cnt1 > 0) {printf("%d ",now);cnt1--;}
        n = cnt2;
        now <<= 1;
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值