Educational Codeforces Round 145 (Rated for Div. 2) C. Sum on Subarrays 题解

题意

Codeforces Educational Codeforces Round 145 (Rated for Div. 2) C. Sum on Subarrays

给你 \(n\)\(k\) ,要求生成一个长度为 \(n\) 的数组 \(a\),且他的非空正子数组的数量为 \(k\) ,非空负子数组的数量为 \(n-k\),且 \(a\) 的元素取值范围为 \([-1000, 1000]\)

思路

题目解法很多,而我一个都不会(

分类讨论n和k的关系:

  • n > k: 那么第k个为一个大整数,所有右端点为k的子数组都是正数组,而且右边的子数组不被第k个数给影响了。即前k-1个设置为-1,第k个设置为100(大于30就行),第k+1个大于第k个,后面的继续-1.
  • n = k: 那么第k个为一个大整数,所有右端点为k的子数组都是正数组。即前k-1个设置为-1,第k个设置为100。
  • n < k: 那么第n个数设置为最大值,剩下左边的n-1个位置再整k-n个正子数组。即第n个位置为1000,递归处理(n-1, k-n)。

注意可能卡常(我用vector被卡了

代码

#include <iostream>
#include <algorithm>
#include <vector>
 
using namespace std;
 
const int N = 500;
int res[N];
 
void getarray(int n, int k) {  
    if(k < n) {
        if(k >= 1) {
            for(int i=1; i<=k-1; i++) res[i] = -1;
            res[k] = 100;
            res[k+1] = -200;
            for(int i=k+2; i<=n; i++) res[i] = -1;
        }
        else {
            for(int i=1; i<=n; i++) res[i] = -1;
        }
        
    }
    else if(k == n) {
        for(int i=1; i<=k-1; i++) res[i] = -1;
        res[k] = 1000;
    }
    else {
        getarray(n-1, k-n);
        res[n] = 1000;
    }
}
 
void solve() {
    int n, k; scanf("%d%d", &n, &k);
 
    getarray(n, k);
 
    for(int i=1; i<=n; i++) printf("%d%c", res[i], " \n"[i==n]);
 
}
 
int main() {
    int t; scanf("%d", &t);
    while(t--) {
        solve();
    }
    return 0;
}
posted @ 2023-04-13 00:06  1v7w  阅读(29)  评论(0编辑  收藏  举报