题解Photoshoot 【USACO 2020, Bronze】

话不多说,先上题目

Farmer John 在给他编号为 1…N的 N 头奶牛排队拍照(2≤N≤10^3)。FJ 一开始计划从左向右数第 i 个位置排编号为 ai 的奶牛,他在一张纸上写下了排列 a1,a2,…,aN。不幸的是,这张纸刚刚被 Farmer Nhoj 偷走了!

幸好 FJ 仍然有机会恢复他之前写下的排列。在这张纸被偷走之前,Bessie 记录了序列 b1,b2,…,bN−1,对于每一个 1≤i<N 满足 b(i)=a(i)+a(i+1)。

基于 Bessie 的信息,帮助 FJ 恢复可以产生序列 b 的“字典序最小”的排列 a。排列 x 字典序小于排列 y,如果对于某个 j,对于所有 i<j均有 xi=yi,且有 xj<yj(换句话说,这两个排列到某个位置之前都相同,在这个位置上 x 小于 y)。保证存在至少一个满足条件的 a。


输入格式(Format Input)
输入的第一行包含一个整数 N。
第二行包含 N−1 个空格分隔的整数 b1,b2,…,bN−1。
输出格式(Format Output)
输出一行,包含 N 个空格分隔的整数 a1,a2,…,aN。

输入样例 1(Sample Input 1)
5
4 6 7 6
输出样例 1(Sample Output 1)
3 1 5 2 4
限制(Restrictions)
时间限制(Time Limit):  1000 ms
内存限制(Memory Limit):  65536KB

说明/提示(Hint)
a 能够产生 b,因为 3+1=4,1+5=6,5+2=7,2+4=6。

测试点性质:
测试点 2-4 满足 N≤8。
测试点 5-10 没有额外限制。

题目就是要求原来的系列,因为牛的数量不可能是负的或是0,而且n数量级别不大,我们可以用暴力枚举1~第一个数大小(牛编号肯定小于第一个数大小)的每一种可能,判断是否成立,

#include<bits/stdc++.h>

using namespace std; 
int a[100100],b[100010];
int main(){
	int n;
	scanf("%d",&n);
	memset(b,0,sizeof(b));
	for(int i=1;i<=n-1;i++)
	{
		scanf("%d",&a[i]);
	//注意输入的·是n-1个数
		
	}
	
	
	int fl=0;
	for(int i=1;i<=a[1];i++)
	{
		b[1]=i;
		for(int j=2;j<=n;j++)
		{
			b[j]=a[j-1]-b[j-1];
			//枚举每一种可能的排列,记录在数组里
		}
		fl=0;
		for(int j=1;j<=n;j++)
		{
			for(int k=1;k<=n;k++)
			{
				if((b[j]==b[k]&&j!=k)||(b[k]<=0))//判断是否有重复的牛或《=0的牛,
                 //不成立就记为0
				{
					fl=1;
					break;
				}
			}
			if(fl==1)
			{
				break;//不成立
			}
		}
		if(fl==0)//可能性成立
		{
			for(int j=1;j<=n;j++)
			{
				printf("%d ",b[j]);
				
			}
			return 0;//直接结束
		}
		memset(b,0,sizeof(b));//清空每一种可能的排列
	}
	
	return 0;
}

亲测可过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值