训练情况
赛后反思
被A题吓了一跳,发现是结论题,C题构造思维定式了,以为一定要凑 \(a_1\),实则可以再找一个超过 \(b_i\) 值域的数
A题
平均数可以倒过来求数列和,所以这题只需要判断数列的和除以 n 是否等于 m 即可
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'using namespace std;void solve(){int n,m; cin>>n>>m;vector<int> a(n + 1);int sum = 0;for(int i = 1;i<=n;i++) cin>>a[i],sum += a[i];if(sum%n==0&&sum/n==m) cout<<"YES"<<endl;else cout<<"NO"<<endl;
}signed main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T; cin>>T; while(T--)solve();return 0;
}
B题
手玩题,我们发现对于 \(k\) 奇数的情况,答案至少是 \(1\),因为出口那个人要传送奇数次,所以初始在出口那个人一定不在出口,最近只能在 \(n-1\) 了,剩下的人全部传送到出口,对于 \(k\) 偶数的情况下,答案至少是 \(0\),可以借助 \(n-1\) 中转一次到 \(n\),初始在出口的那个人偶数次还是在出口,按照手玩结论分类讨论即可
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'using namespace std;void solve(){int n,k; cin>>n>>k;if(k&1){for(int i = 1;i<n;i++) cout<<n<<" ";cout<<n-1<<endl;} else {for(int i = 1;i<n-1;i++) cout<<n-1<<" ";cout<<n<<" "<<n-1<<endl;}
}signed main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T; cin>>T; while(T--)solve();return 0;
}
C题
这题我们观察到 \(a_i\) 值域比 \(b_i\) 大很多,所以我们找出来的那个数要尽可能大,比 \(b_i\) 值域更大就不会重复了,公式移项我们可以发现数列的奇数项和等于偶数项和,对于长度为奇数的数列,奇数项会比偶数项多一个,所以我们排序后把最大的数都放在奇数项,其他的放在偶数项,这样构造找出来的数一定是大于 \(b_i\) 值域的,因为奇数项多一个,奇数项和为 \(\sum_{i=1}^{n}{a_i} + a_n\),减去 \(n\) 个偶数项,凑出来的数一定是 \(a_n\) 加一个正数,所以保证不会重复,按照这个思路构造即可
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'using namespace std;void solve(){int n; cin>>n;vector<int> a(3*n);map<int,int> v;for(int i = 1;i<=2*n;i++) cin>>a[i],v[a[i]] = 1;sort(a.begin() + 1,a.begin() + 1 + 2*n);int sum1 = 0,sum2 = 0;for(int i = n;i<=2*n;i++) sum1 += a[i];for(int i = 1;i<n;i++) sum2 += a[i];cout<<a[n]<<" "<<sum1-sum2<<" ";for(int i = n+1;i<=2*n;i++){if(i == 2*n) cout<<a[i]<<" ";else cout<<a[i]<<" "<<a[i-n]<<" ";}cout<<endl;
}signed main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T; cin>>T; while(T--)solve();return 0;
}