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
浙公网安备 33010602011771号