CCF CSP 再卖菜 c++ java python 201809_4
问题描述
在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜。
第一天,每个商店都自己定了一个正整数的价格。店主们希望自己的菜价和其他商店的一致,第二天,每一家商店都会根据他自己和相邻商店的价格调整自己的价格。具体的,每家商店都会将第二天的菜价设置为自己和相邻商店第一天菜价的平均值(用去尾法取整)。
注意,编号为1的商店只有一个相邻的商店2,编号为n的商店只有一个相邻的商店n-1,其他编号为i的商店有两个相邻的商店i-1和i+1。
给定第二天各个商店的菜价,可能存在不同的符合要求的第一天的菜价,请找到符合要求的第一天菜价中字典序最小的一种。b1
字典序大小的定义:对于两个不同的价格序列(a1, a2, …, an)和(b1, b2, b3, …,bn),若存在i (i>=1), 使得ai<bi,且对于所有j<i,aj=bj,则认为第一个序列的字典序小于第二个序列。
输入格式
输入的第一行包含一个整数n,表示商店的数量。
第二行包含n个正整数,依次表示每个商店第二天的菜价。
输出格式
输出一行,包含n个正整数,依次表示每个商店第一天的菜价。
样例输入
8
2 2 1 3 4 9 10 13
样例输出
2 2 2 1 6 5 16 10
数据规模和约定
对于30%的评测用例,2<=n<=5,第二天每个商店的菜价为不超过10的正整数;
对于60%的评测用例,2<=n<=20,第二天每个商店的菜价为不超过100的正整数;
对于所有评测用例,2<=n<=300,第二天每个商店的菜价为不超过100的正整数。
请注意,以上都是给的第二天菜价的范围,第一天菜价可能会超过此范围。
问题分析
看到这道题,首先想到的就是深搜,但提交后才发现会运行超时,只能得80分,去查了别人的博客后,发现有人是用线性差分做的,还有的人设置了一个三维数组,然后在搜索时先判断是否之前访问过,没有访问过的话再进行搜索,但我始终没有想明白那个数组的意义,所以如果你知道如何解释那个三维数组,欢迎大佬在评论区指教。我的代码如下:
c++代码如下
#include<cstdio>
#include<stdlib.h>
const int MAXN = 305;
int array[MAXN];
int target[MAXN];
int number;
int main(){
void dfs(int index);
scanf("%d",&number);
for(int i = 1;i <= number;i++){
scanf("%d",&array[i]);
}
for(int i = 1;i <= 2 * array[1];i++){
target[1] = i;
target[2] = 2 * array[1] - target[1];
if(target[2] > 0){
dfs(2);
}
target[2] = 2 * array[1] - target[1] + 1;
if(target[2] > 0){
dfs(2);
}
}
return 0;
}
void dfs(int index){
if(index == number - 1){
int temp = 3*array[index]-target[index-1];
if((temp/2==array[number])||(temp+1)/2==array[number] ||(temp+2)/2==array[number]){
for(int i = 1;i <= number - 1;i++){
printf("%d ",target[i]);
}
for(int i = 0;i < 3;i++){
if((temp+i)/2==array[number]){
printf("%d",3*array[index]+i-target[index]-target[index-1]);
exit(0);
}
}
}
}
for(int i = 0;i < 3;i++){
target[index+1] = 3 * array[index]-target[index] - target[index-1] + i;
if(target[index+1] > 0){
dfs(index+1);
}
}
}
结果会运行超时,只能得80分。
Java代码如下:
import java.util.Scanner;
public class csp201809_4 {
public static int[] a = new int[305];
public static int[] b = new int[305];
public static int number;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
number = input.nextInt();
for(int i = 1;i <= number;i++) {
a[i] = input.nextInt();
}
for(int i = 1;i <= 2 * a[1];i++) {
b[1] = i;
b[2] = 2*a[1]-b[1];
if(b[2] > 0) {
dfs(2);
}
b[2] = 2 * a[1] - b[1] + 1;
if(b[2] > 0) {
dfs(2);
}
}
}
public static void dfs(int index) {
if(index == number - 1) {
if((3*a[index]-b[index-1])/2==a[number]||(3*a[index]-b[index-1]+1)/2==a[number]||(3*a[index]-b[index-1]+2)/2==a[number]) {
for(int i = 1;i <= number-1;i++) {
System.out.print(b[i] + " ");
}
for(int i = 0;i < 3;i++) {
if((3*a[index]-b[index-1]+i)/2==a[number]) {
System.out.print(3*a[index]-b[index]-b[index-1]+i);
System.exit(0);
}
}
}
}
for(int i = 0;i < 3;i++) {
b[index+1] = 3 * a[index] - b[index] - b[index - 1] + i;
if(b[index+1] > 0) {
dfs(index+1);
}
}
}
}
结果会运行超时,只能得80分。
python3代码如下:
import sys
number = int(input())
temp = input().split(" ")
array = [0]*(number+5)
target = [0]*(number+5)
def dfs(index):
if index == number - 1:
temp = 3 * array[index]-target[index-1]
if (temp // 2 == array[number]) or ((temp+1) // 2 == array[number]) or ((temp+2) // 2 == array[number]):
for i in range(1,number):
print((str(target[i])+" "),end="")
for i in range(3):
if ((temp+i) // 2 == array[number]):
print(3 * array[index]+i-target[index]-target[index-1],end="")
sys.exit(0)
for i in range(3):
target[index + 1] = 3 * array[index]-target[index] - target[index-1] + i
if (target[index+1] > 0):
dfs(index+1)
if __name__=="__main__":
for i in range(1,number+1):
array[i] = int(temp[i - 1])
for i in range(1,2*array[1]+1):
target[1] = i
target[2] = 2 * array[1] - target[1]
if target[2] > 0:
dfs(2)
target[2] = 2 * array[1] - target[1] + 1
if target[2] > 0:
dfs(2)
如果大佬有更好的方法,欢迎在评论区指教。