洛谷 2320 & bzoj 1192 题解 (思维,构造)

该博客主要解析了洛谷2320和bzoj1192题目,涉及如何构造一个序列,使得[1, n]中的所有整数都是序列中元素的和,并保证序列字典序最小。作者通过回忆初中时期的类似问题,提出采用类似二进制拆分的方法,即按位上取整,来解决构造序列的问题。预计序列长度为logn级别,对于n=1e9的情况,也只需约30步。博客提供了问题的解决思路,并未展示具体代码。" 139323119,9280705,畅捷通T+软件业务流程详解,"['会计软件', '企业管理', '业务流程', '账务处理', 'T+软件']

原题链接:
洛谷
bzoj

题意简述

给定一个 n ( &lt; = 1 e 9 ) n(&lt;=1e9) n(<=1e9),构造一个序列使得:

  1. [ 1 , n ] [1,n] [1,n]中所有整数是这个序列中某些元素的和
  2. 字典序最小

输出这个序列

思路

我们一开始认为: n n n 1 e 9 1e9 1e9,这个序列怎么也是 1 e 8 1e8 1e8,但是为什么还要输出呢?不是要 O L E OLE OLE。。。

仔细想想,并不是这样的。此时我突然想起了我们***初中初一期末考试题。和这个题一模一样,只是 n = 15 n=15 n=15

我当时构造了一个 1 , 2 , 4 , 8 1,2,4,8 1,2,4,8。当时我的数学水平还没有现在掉的这么严重(只有全市前 100 100 100),那个时候我是前 20 20 20(我在江苏省苏州市)。对于当时做数学题经验丰富的我来说,构造这个并不难。

回忆一下当时的构造方法, 1 , 2 , 4 , 8 1,2,4,8 1,2,4,8。没错,我们只要类似“二进制拆分”就珂以了!!!所以,粗略估计答案长度是 l o g n logn logn级别的,即使 n = 1 e 9 n=1e9 n=1e9,也只有 30 30 30多一点。

但是并不是所有时候都是直接二进制拆分的,我们还要保证字典序最小。比如 n = 6 n=6 n=6的时候,应该是 1 , 2 , 3 1,2,3 1,2,3,而不是 1 , 2 , 4 1,2,4 1,2,4。这个问题很好解决,我们只要把暴力二进制拆分中的下取整改成上取整就好了。(即 ( n + 1 ) / 2 (n+1)/2 (n+1)/2

代码:

#include<bits/stdc++.h>
using namespace std;
namespace Flandle_Scarlet
{
    int n;
    void Soviet()
    {
        int cnt=0;
        int a[40];
        while(n)
        {
            a[++cnt]=(n+1)/2;//这里改成(n+1)/2
            n>>=1;
        }
        printf("%d\n",cnt);
        sort(a+1,a+cnt+1);
        for(int i=1;i<=cnt;++i)
        {
            printf("%d ",a[i]);
        }putchar('\n');
    }
    void IsMyWife()
    {
        if (0)
        {
            freopen("","r",stdin);
            freopen("","w",stdout);
        }
        cin>>n;
        Soviet();
    }
};
int main()
{
    Flandle_Scarlet::IsMyWife();
    return 0;
}

回到总题解界面

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值