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

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);
}

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/88698964