180904 再卖菜 ccf

思路ios

dfs+去重数组

关键函数

满分的关键在于不一样的前缀可能会遇到相同的状况,要直接排除这些状况,避免重复计算(单纯dfs只有80分)spa

实现code

这里采用数组f来记录各类状况,经过traceback函数回溯blog

 1 #include<iostream>
 2 #include<cstring>
 3 
 4 using namespace std;
 5 
 6 int a[305]; 7 int b[305]; 8 bool f[305][305][305];//去重
9 //int s=0; 10 int n; 11 void traceback(int i,int b1,int b2){ 12 /*if(s==1){ 13 return; 14 }*/ 15 if(f[i][b1][b2])return; 16 f[i][b1][b2]=true; 17 if(i>=n){ 18 if((b1+b2)/2==a[n-1]){ 19 for(int j=0;j<n;j++){ 20 cout<<b[j]<<' '; 21 } 22 exit(0); 23 } 24 25 } 26 else{ 27 for(int j=0;j<3;j++){//考虑除法取整的状况 28 b[i]=a[i-1]*3+j-b2-b1; 29 if(b[i]<=0){ 30 continue; 31 } 32 traceback(i+1,b[i],b[i-1]); 33 /*if(s==1){ 34 return; 35 }*/ 36 } 37 } 38 return; 39 } 40 41 int main(){ 42 memset(f,false,sizeof(f)); 43 cin>>n; 44 for(int i=0;i<n;i++){ 45 cin>>a[i]; 46 } 47 48 int lim=2*a[0]; 49 for(int i=1;i<=lim;i++){ 50 b[0]=i; 51 for(int j=0;j<2;j++){//考虑除法取整的状况 52 b[1]=lim+j-b[0]; 53 if(b[1]<=0){ 54 continue; 55 } 56 traceback(2,b[1],b[0]); 57 /*if(s==1){ 58 return 0; 59 }*/ 60 } 61 } 62 63 return 0; 64 }

题目ci

问题描述
  在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜。
  第一天,每一个商店都本身定了一个正整数的价格。店主们但愿本身的菜价和其余商店的一致,次日,每一家商店都会根据他本身和相邻商店的价格调整本身的价格。具体的,每家商店都会将次日的菜价设置为本身和相邻商店第一天菜价的平均值(用去尾法取整)。
  注意,编号为1的商店只有一个相邻的商店2,编号为n的商店只有一个相邻的商店n-1,其余编号为i的商店有两个相邻的商店i-1和i+1。
  给定次日各个商店的菜价,可能存在不一样的符合要求的第一天的菜价,请找到符合要求的第一天菜价中字典序最小的一种。
  字典序大小的定义:对于两个不一样的价格序列(a 1, a 2, ..., a n)和(b 1, b 2, b 3, ..., b n),若存在i (i>=1), 使得a i<b i,且对于全部j<i,a j=b j,则认为第一个序列的字典序小于第二个序列。
 
输入格式
  输入的第一行包含一个整数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的正整数。   请注意,以上都是给的次日菜价的范围,第一天菜价可能会超过此范围。
相关文章
相关标签/搜索