问题描述
在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜。
第一天,每个商店都自己定了一个正整数的价格。店主们希望自己的菜价和其他商店的一致,第二天,每一家商店都会根据他自己和相邻商店的价格调整自己的价格。具体的,每家商店都会将第二天的菜价设置为自己和相邻商店第一天菜价的平均值(用去尾法取整)。
注意,编号为1的商店只有一个相邻的商店2,编号为n的商店只有一个相邻的商店n-1,其他编号为i的商店有两个相邻的商店i-1和i+1。
给定第二天各个商店的菜价,可能存在不同的符合要求的第一天的菜价,请找到符合要求的第一天菜价中字典序最小的一种。
字典序大小的定义:对于两个不同的价格序列(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的正整数。
请注意,以上都是给的第二天菜价的范围,第一天菜价可能会超过此范围。
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int cur_edge=0;
int dist[305]= {0}; //距离原点最短路径
int inqueue[305]; //在队列中的次数
int flag[305]; //是否在队列中
int a[305]={0}; //第二天的价格
int head[305];//为起始位置相同边所形成链表构造的一个头
int num;
struct Edge
{
int to;
int next;//起始位置相同的边形成一个链表
int len;
}edge[2000];
void addEdge(int from ,int to,int len)
{
edge[cur_edge].to=to;
edge[cur_edge].len=len;
edge[cur_edge].next=head[from];
head[from]=cur_edge;
cur_edge++;
}
void spfa()//shortest path fastest algorithm
{
queue<int>que;
for(int i=0;i<=num;i++)
{
que.push(i);
flag[i]=1;
inqueue[i]=1;
}
while(!que.empty())
{
int from=que.front();
que.pop();
flag[from]=0;
if(inqueue[from]>=num)
{
cout<<"出现负环,无解"<<endl;
return;
}
for(int i=head[from];i!=-1;i=edge[i].next)
{
int to=edge[i].to;
if(dist[to]-dist[from]<edge[i].len)
{
dist[to]=dist[from]+edge[i].len;
if(flag[to]==0) //对于更新的点,如果不在队列则加入队列
{
que.push(to);
inqueue[to]++;
flag[to]=1;
}
}
}
}
return ;
}
int main()
{
cin>>num;
for(int i=1;i<=num;i++)
cin>>a[i];
memset(head,-1,sizeof(head));
for(int i=0;i<=num-3;i++)
{
addEdge(i,i+3,a[i+2]*3);
addEdge(i+3,i,-(a[i+2]*3+2));
}
addEdge(0,2,a[1]*2);
addEdge(2,0,-(a[1]*2+1));
addEdge(num-2,num,a[num]*2);
addEdge(num,num-2,-(a[num]*2+1));
for(int i=0;i<num;i++) //每个定价至少为1
addEdge(i,i+1,1);
spfa();
for(int i=1;i<=num;i++)
{
a[i]=dist[i]-dist[i-1];
cout<<a[i]<<" ";
}
return 0;
}