Codeforces Problemset problem 1129 B Wrong Answer —— 构造数组

博客围绕一个算法问题展开,给定数组求sum*len最大值,小明的程序有误。要求构造长度不超2000、元素绝对值不超1e6的数组,使正确答案与小明代码答案差为k。题解提出构造2000长度数组,让k变为2000倍数,找出合适的数满足条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Consider the following problem: given an array a containing n integers (indexed from 0 to n−1), find max0≤l≤r≤n−1∑l≤i≤r(r−l+1)⋅ai. In this problem, 1≤n≤2000 and |ai|≤106.

In an attempt to solve the problem described, Alice quickly came up with a blazing-fast greedy algorithm and coded it. Her implementation in pseudocode is as follows:

function find_answer(n, a)
# Assumes n is an integer between 1 and 2000, inclusive
# Assumes a is a list containing n integers: a[0], a[1], …, a[n-1]
res = 0
cur = 0
k = -1
for i = 0 to i = n-1
cur = cur + a[i]
if cur < 0
cur = 0
k = i
res = max(res, (i-k)*cur)
return res

Also, as you can see, Alice’s idea is not entirely correct. For example, suppose n=4 and a=[6,−8,7,−42]. Then, find_answer(n, a) would return 7, but the correct answer is 3⋅(6−8+7)=15.

You told Alice that her solution is incorrect, but she did not believe what you said.

Given an integer k, you are to find any sequence a of n integers such that the correct answer and the answer produced by Alice’s algorithm differ by exactly k. Note that although the choice of n and the content of the sequence is yours, you must still follow the constraints earlier given: that 1≤n≤2000 and that the absolute value of each element does not exceed 106. If there is no such sequence, determine so.

Input
The first and only line contains one integer k (1≤k≤109).

Output
If there is no sought sequence, print “-1”.

Otherwise, in the first line, print one integer n (1≤n≤2000), denoting the number of elements in the sequence.

Then, in the second line, print n space-separated integers: a0,a1,…,an−1 (|ai|≤106).

Examples
inputCopy
8
outputCopy
4
6 -8 7 -42
inputCopy
612
outputCopy
7
30 -12 -99 123 -2 245 -300
Note
The first sample corresponds to the example given in the problem statement.

In the second sample, one answer is n=7 with a=[30,−12,−99,123,−2,245,−300], in which case find_answer(n, a) returns 1098, while the correct answer is 1710.

题意:

假设一段区间的和为sum,长度为len,让你在一个数组里找出sum*len最大为多少,小明写了一个程序,如上,但是很明显是错的,现在他的问题是让你构造一个长度不超2000的数组,且每个值不超过1e6,使得正确答案与小明代码算出来的答案的差为k。

题解:

它数组长度最多为2000,那么我们就构造一个2000的数组,使得它满足条件。什么时候正确答案与小明的答案会有差别呢?小明是如果这一段的和为负数了,那么就不计入答案,但是有时候计入答案会更好,比如说 -1 -1 100,小明的答案就是100,但是如果三个都取,答案就是983.我们要相差k,如果直接这样算会很麻烦,而且k如果是质数就除不尽了,那么我们就让k变成2000的倍数,怎么样才能让它变成2000的倍数,最简单的方法就是只让最后一个值是正数,倒数第二个值是负数,其他的全为0,就可以让k+最后一个数为2000的倍数,那么我们要做的就是找出这个数,使得 k+最后一个数=2000(倒数第二个数+最后一个数)。那么倒数第二个数=(k+最后一个数-2000*最后一个数)/2000,然后我们必须让倒数第二个数是负数,这样才能只让最后一个数计入答案。所以最后一个数要大于5e5,然而范围是1e6,那么我们直接让最后一个数=1e6-2000%mod即可。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int k;
    scanf("%d",&k);
    int x=1000000-k%2000;
    int y=(k+x-2000*x)/2000;
    printf("2000\n");
    for(int i=1;i<=1998;i++)
        printf("0 ");
    printf("%d %d\n",y,x);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值