题目:Codeforces Round #842 (Div. 2)
A. Greatest Convex
题意:给定数k,选取x(1<=x<k),使得(x-1)!+x! 为k的倍数,输出可得到的最大x
思路:拿到题目的一瞬间,我以为直接暴力枚举,算阶乘相加再判断是否可以整除,但过后发现k最大可取到1e9,显然会超时。因此应选取其他方法。首先我们观察到(x-1)!+x! = (x+1)*(x-1)!即它可整除1~x+1中除x外的任何整数,所以当 x+1为k时,即为x的最大取值x=k-1。
AC_code:
#include<bits/stdc++.h>
using namespace std;
void solve(){
int k; cin >> k;
//注意:应当特判一下k=1的情况
if(k == 1) cout << -1 << endl;
cout << k - 1 << endl;
}
int main ()
{
ios::sync_with_stdio(false);
cin.tie(); cout.tie();
int t; cin >> t;
while(t--) solve();
return 0;
}
B. Quick Sort
题意:给定序列p与数字k,从序列p中选取k个数并将其删除,然后将他们按升序排列后插入再序列末端,输出最少的操作次数
思路:先判断原序列中有多数个数已经成功排列(即1 2 3 4....),并记录下来。排好的则无需再排,只需排列未排好的。再用未排好的元素数量除以每次可操作数,并将结果向上取整即可得出答案。
AC_code:
#include<bits/stdc++.h>
using namespace std;
void solve() {
int n, k;
cin >> n >> k;
vector<int> p(n);
for (int i = 0; i < n; i++) cin >> p[i];
int res = 0;
int cnt = 1;
for (int i = 0; i < n; i++) {
if (p[i] == cnt) cnt++;
}
if((n - cnt + 1) % k == 0) res = (n - cnt + 1) / k;
else res = (n - cnt + 1) / k + 1;
cout << res << endl;
}
int main ()
{
ios::sync_with_stdio(false);
cin.tie(); cout.tie();
int t; cin >> t;
while(t--) solve();
return 0;
}
C. Elemental Decompress
题意:给定数组a,若存在序列p,q使得任意的a[i]都有a[i]=max(p[i],q[i]),则输出yes并打印出序列p,q,否则输出no
思路:首先用一个map将a[i]与其出现的次数储存下来在,当a[i]出现的次数超过2时,则输出no。再用一个vector储存1~n中a里没有出现的元素。然后若a[i]出现了两次,则令p[i]=q[j]=a[i],p[j]=q[i]=x其中x为vector中比a[i]小的最大数,若x不存在,则输出no(因为如果这样则说明1~n存在x没有在a中出现,但x会与p,q中出现,矛盾)。而对于寻找x,我们则可以使用upper_bound(v.begin(),v.end(),x,greate<int>()),查询降序容器中第一个小于x的数,并返回这个数的指针。
AC_code:
#include <bits/stdc++.h>
using namespace std;
int a[200005], p[200005], q[200005];
void solve(){
int n; cin >> n;
map<int, int> mp, mmp;
vector<int> v;
int pp = 1;
for (int i = 1; i <= n; i++){
cin >> a[i];
mp[a[i]]++;
if(mp[a[i]] > 2) pp = 0;
}
if(!pp){
cout << "NO" << endl;
return;
}
for(int i = n; i >= 1; i--){
if(!mp[i]){
v.push_back(i);
}
}
for(int i = n; i >= 1; i--){
if(mp[a[i]] == 1){
p[i] = a[i];
q[i] = a[i];
}
else if(!mmp[a[i]]){
p[i] = a[i];
auto t = upper_bound(v.begin(), v.end(), a[i], greater<int>());
if(t == v.end()){
cout << "NO" << endl;
return ;
}
q[i] = *t;
mmp[a[i]] = *t;
v.erase(t);
}
else{
q[i] = a[i];
p[i] = mmp[a[i]];
}
}
cout << "YES" << endl;
for(int i = 1; i <= n; i++) cout << p[i] << " ";
cout << endl;
for(int i = 1; i <= n; i++) cout << q[i] << " ";
cout << endl;
}
int main ()
{
ios::sync_with_stdio(false);
cin.tie(); cout.tie();
int t; cin >> t;
while (t--) solve ();
return 0;
}