人生的起落

文章讲述了如何通过编程方法构造一个数字序列,满足特定的出现次数规则。当n>3且k=0时,序列为111...;当k不为0时,根据n和k的关系,使用2121模式并进行调整。代码展示了详细的逻辑和步骤。
摘要由CSDN通过智能技术生成

题意

思路

全部按 2 1 2 1 构造

情况比较多:

n = 1 只有 k = 0 才能满足

n = 2 只有k = 0 才能满足

(1) n >= 3的时候才可以有:

k = 0 直接 1 1 1 …… s-n+1 构造

(2) k != 0:

首先 n < 2 * k + 1 是不可能的

n > 2 * k + 1 的时候直接 2 1 2 1……(n-(3 * k + 2)-(n-2*k+1-1))

由于是恰好出现k次 所以在第2*k+2的数字一定把他搞大一点 后面全是1就行(这里怎么凑都行)

(3) n = 2 * k + 1 才需要考虑:

需要判断经过 2 1 2 1的摧残后 s还剩下多少 我需要把s尽可能的均分给所有 2

如果剩下的不足以(k+1)次 也就是奇数位2的消耗大于剩下来的s 就肯定不行

那如果可以就把所有的2 + tmp(均分的)

剩下的1的位置各自加1直到 s剩 耗尽

代码

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define ft first
#define sd second
#define int long long
//#define i8 __int128
#define endl '\n'
#define ull unsigned long long
using namespace std;
typedef long long ll;
const double pi = acos(-1.0); //圆周率
const int mod = 1e9 + 7;
const int inf = 1e18;
const int N = 2e5 + 10;
typedef pair<int, int>pii;
/******************/
int a[N];
void solve()
{
    int n, s, k;
    cin >> n >> s >> k;
    if (n == 1)
    {
        if (k != 0)cout << -1 << endl;
        else
            cout << s << endl;
        return;
    }
    if (n == 2)
    {
        if (k != 0) cout << -1 << endl;
        else
            cout << s / 2 << ' ' << s - s / 2 << endl;
        return;
    }
    if (k == 0)
    {
        for (int i = 1; i <= n - 1; i++)
            cout << 1 << " ";
        cout << s - n + 1 << endl;
        return;
    }
    if (n < 2 * k + 1) { cout << -1 << endl; return; }
    if (k && s < n + k + 1) { cout << -1 << endl; return; }

    for (int i = 1; i <= 2 * k - 1; i += 2)
    {
        a[i] = 2; a[i + 1] = 1;
    }
    a[2 * k + 1] = 2;
    int left = n - (2 * k + 1);//剩余位数
    s -= (3 * k + 2);//剩余值
    if (left != 0)
    {
        a[2 * k + 2] = s - left + 1;
        for (int i = 2 * k + 3; i <= n; i++)
            a[i] = 1;
    }
    else
    {
        if (s / (k + 1) == 0 && s != 0) { cout << -1 << endl; return; }

        int tmp = s / (k + 1);
        int tmp2 = s % (k + 1)
        for (int i = 1; i <= n; i += 2)
            a[i] += tmp;
        for (int i = 2; i <= n; i += 2)
        {
            if (tmp2 == 0)break;
            --tmp2;
            a[i] += 1;
        }
    }
    for (int i = 1; i <= n; i++)
        cout << a[i] << " ";
    cout << endl;
}
signed main()
{
    IOS;
    int _ = 1;
    cin >> _;
    while (_--)
        solve();
}

写半天没写出来,搬的代码->代码查看 (nowcoder.com)

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值