C. Breach of Faith

题目链接👈

题目描述🥰

题目思路😀

一个很玄妙的构造题,赛时也是一直wa2,不知道怎么去构造😇,越guess越错

题目的思路来自一个大佬🙇‍♀️

首先我们需要考虑到我们构造出来的数是不重复的,所以我们可以把数组排序,用最后的n-1个数减去前面的n-1个数,然后我们可以把这个差值加上剩下的两个数,那么构造出来的数一定是大于原来数组的最大值的,就可以保证构造出来的数的唯一性

举样例来理解一下,如8 6 1 4,排完序->1 4 6 8,那么构造出来的数就是8-1+4+8=17,这个数明显比之前的最大值大,所以保证了这个数字的不重复性

有了这个非常NB的思路我们就可以直接用代码实现了

Question:为什么构造出来的数就满足这个a数组的性质了

用单纯语言解释可能比较抽象,我就结合代码讲一下为什么符合性质

	vector<int>ans(2*n+1);
	int j=1;
	for(int i=1;i<=n-1;i++){
		ans[j++]=b[2*n-i+1];
		ans[j++]=b[i];
		res+=b[2*n-i+1]-b[i];
	}
	res+=b[n]+b[n+1];
	for(int i=1;i<=2*n-2;i++)cout<<ans[i]<<" ";
	cout<<b[n+1]<<" "<<res<<" "<<b[n]<<endl;

首先我们的a数组从第二个元素开始就是偶数下标的数减去奇数下标的数,那么我们要保证我们构造出来的最大值要作为偶数下标,那么就可以把它放到2n的位置,因为a数组的性质,我们需要把偶数下标的数减去奇数下标的数,所以把在构造res过程中加的元素放在奇数下标即可,而把在构造res过程中间的元素放在偶数下标即可,这样就能够满足第一个元素刚好就可以等于(最大值+偶数下标的数和-除了第一个奇数下标的数和)。因为在构造最大值的过程是加上奇数下标的数,这下减去刚刚好抵消,而在构造res的过程中是减去偶数下标的数,这下加上也刚刚好抵消。

比如 8614 我们构造出来的数组是 8 1 6 17 4 ,我们可以把在res构造中加的8 6 4放在奇数下标上,而把减的1放在偶数位,就能够满足a数组的性质

AC代码🧠

// Problem: C. Breach of Faith
// Contest: Codeforces - Codeforces Round 1008 (Div. 2)
// URL: https://codeforces.com/contest/2078/problem/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

#define dev1(a) cout << #a << '=' << a << endl;
#define dev2(a, b) cout << #a << " = " << a << "  " << #b << " = " << b << endl;
#define dev3(a, b, c) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << endl;
#define dev4(a, b, c, d) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << "  " << #d << " = " << d << endl;
#define dev5(a, b, c, d, e) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << "  " << #d << " = " << d << "  " << #e << " = " << e << endl;
#define vec(a)                         \
    for (int i = 0; i < a.size(); i++) \
        cout << a[i] << ' ';           \
    cout << endl;
#define darr(a, _i, _n)               \
    cout << #a << ':';                \
    for (int ij = _i; ij <= _n; ij++) \
        cout << a[ij] << ' ';         \
    cout << endl;           
#define cin(a,n)           \
     for(int i=0;i<n;i++) \
      cin>>a[i];          
#define endl "\n"
#define pow pim
int pim(int a,int k)
{
    int res=1;
    if(a==0)return 0;
    while(k) 
    {
        if(k&1)res=(int)res*a;
        k>>=1;
        a=(int)a*a;
    }
    return res;
}
#define fi first
#define se second
#define caseT \
    int T;    \
    cin >> T; \
    while (T--)
#define int long long
// #define int __int128

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 99999999;

// const int N = ;
int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}
 
int lcm(int a, int b)
{
    return a * b / gcd(a, b);
}
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

void solve()
{
	int n;
	cin>>n;
	vector<int>b(2*n+1);
	for(int i=1;i<=n*2;i++)cin>>b[i];
	sort(b.begin()+1,b.begin()+2*n+1);
	int res=0;
	vector<int>ans(2*n+1);
	int j=1;
	for(int i=1;i<=n-1;i++){
		ans[j++]=b[2*n-i+1];
		ans[j++]=b[i];
		res+=b[2*n-i+1]-b[i];
	}
	res+=b[n]+b[n+1];
	for(int i=1;i<=2*n-2;i++)cout<<ans[i]<<" ";
	cout<<b[n+1]<<" "<<res<<" "<<b[n]<<endl;
}

signed main()
{

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	caseT
    solve();
    return 0;
}
/*

*/

 

 posted on 2025-03-11 12:58  熙玺  阅读(373)  评论(0)    收藏  举报

Shu-How Zの小窝

Loading...