C. Restore the Array

C. Restore the Array

题目链接

构造

这个题需要发掘一下题目所给的 b 数组所具有的性质 这个题需要发掘一下题目所给的b数组所具有的性质 这个题需要发掘一下题目所给的b数组所具有的性质
既然是相邻两项中的较大的数组成的数列,所以不会出现 151 既然是相邻两项中的较大的数组成的数列,所以不会出现1 5 1 既然是相邻两项中的较大的数组成的数列,所以不会出现151
这个性质可以自己举例子试试因为 15 后面的数是和 5 取 m a x 所以不可能比 5 小 这个性质可以自己举例子试试因为15后面的数是和5取max所以不可能比5小 这个性质可以自己举例子试试因为15后面的数是和5max所以不可能比5
这种先上升后立即下降的情况,只会是不是严格单调递减 这种先上升后立即下降的情况,只会是不是严格单调递减 这种先上升后立即下降的情况,只会是不是严格单调递减
或者不是严格单调递增 或者不是严格单调递增 或者不是严格单调递增
比如 112 , 441 这种平滑的情况 比如1 1 2, 4 4 1这种平滑的情况 比如112441这种平滑的情况
这样的话我们就发现每三个数中的排第二大的数一定是中间的这个数 这样的话我们就发现每三个数中的排第二大的数一定是中间的这个数 这样的话我们就发现每三个数中的排第二大的数一定是中间的这个数
所以我们就利用这个性质来构造 a 数组,所以我们 a 数组每次取 b 数组中相邻两项中的较小值 所以我们就利用这个性质来构造a数组,所以我们a数组每次取b数组中相邻两项中的较小值 所以我们就利用这个性质来构造a数组,所以我们a数组每次取b数组中相邻两项中的较小值
因为这样我们 a 数组再相邻两项取 m a x 就能得到三个数中间位置的那个数 因为这样我们a数组再相邻两项取max就能得到三个数中间位置的那个数 因为这样我们a数组再相邻两项取max就能得到三个数中间位置的那个数
这样下来我们不会得到 b 数组中的第一个和最后一个,需要我们手动添加进去 这样下来我们不会得到b数组中的第一个和最后一个,需要我们手动添加进去 这样下来我们不会得到b数组中的第一个和最后一个,需要我们手动添加进去
而且手动添加进去仍然满足题目要求,因为我们都是取的相邻两项的较小值 而且手动添加进去仍然满足题目要求,因为我们都是取的相邻两项的较小值 而且手动添加进去仍然满足题目要求,因为我们都是取的相邻两项的较小值
即 a 中的第一个是 b [ 0 ] 和 b [ 1 ] 中的较小的,所以在 a 前面再加一个 b [ 0 ] 再取 m a x 得到的一定是 b [ 0 ] 最后一个一样的道理 即a中的第一个是b[0]和b[1]中的较小的,所以在a前面再加一个b[0]再取max得到的一定是b[0]最后一个一样的道理 a中的第一个是b[0]b[1]中的较小的,所以在a前面再加一个b[0]再取max得到的一定是b[0]最后一个一样的道理

总结

凡是没有 152 这种上升完立马下降的情况下,取相邻两项小者再取相邻两项大者就能得到原数组中间的那个数 凡是没有152这种上升完立马下降的情况下,取相邻两项小者再取相邻两项大者就能得到原数组中间的那个数 凡是没有152这种上升完立马下降的情况下,取相邻两项小者再取相邻两项大者就能得到原数组中间的那个数

code


#include<iostream>
#include<algorithm>
using namespace std;

const int N = 2e5 + 10;

int b[N];
int t, n;

int main()
{
    
    
	cin >> t;
	while(t --)
	{
    
    
		ios::sync_with_stdio(false);
		cin >> n;
		for(int i = 1; i <= n - 1; i ++)
			cin >> b[i];
		
		cout << b[1] << " ";

		for(int i = 2; i <= n-1; i ++)
		{
    
    
			cout << min(b[i], b[i-1]) << " ";
		}
		cout << b[n-1] << endl;

	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_63092029/article/details/129977530