文章目录
A. Greatest Convex
思路分析:
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
void solve(){
// 直接输出减去1的结果即可
int n;
cin >> n;
cout << n - 1 << endl;
}
int main(){
int T;
cin >> T;
while(T -- ) solve();
}
B. Quick Sort
思路分析:
学习积累:
因为每次最多能处理k个数字,当最后还有 k 个数字的时候我们需要多处理一次,也就相当于 x / k 向上取整,其实可以通过数学处理变成向下取整方便代码计算
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
void solve(){
int n, k, f = 1, x;
cin >> n >> k;
for(int i = 0; i < n; i ++ ){
cin >> x;
if(x == f) f ++; // 按照顺序找到 1 2 3 4 ...合法子序列的长度, 之后长度需要减去1
}
// n - (f - 1) + k - 1 = n - f + k
cout << (n - f + k ) / k << endl;
}
int main(){
int T;
cin >> T;
while(T -- ) solve();
}
C. Elemental Decompress
思路分析:
代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 2e5 + 10;
int p[N], q[N]; // 存储最后的结果
int cp[N], cq[N]; // 记录 p 和 q 序列当中数字出现的次数
int c[N], n; // 本身的序列
void out(){
cout << "YES" << endl;
for(int i = 0; i < n; i ++ ) cout << p[i] << ' ';
cout << "\n";
for(int i = 0; i < n; i ++ ) cout << q[i] << ' ';
cout << "\n";
}
void solve(){
cin >> n;
vector<pair<int, int>> v(n); // 存放 值 - 位置
for(int i = 0; i < n; i ++ ){
cin >> c[i];
v[i] = make_pair(c[i], i);
p[i] = q[i] = 0;
cp[i + 1] = cq[i + 1] = 0;
}
sort(v.rbegin(), v.rend()); // 自大到小排序
for(int i = 0; i < n; i ++ ){
// 第一次放入 p 和 q 序列
int a = v[i].first, b = v[i].second;
if(cp[a] == 0){
p[b] = a, cp[a] ++ ;
}
else{
q[b] = a, cq[a] ++ ;
}
}
int r1 = n, r2 = n; // 第二次补充 p 和 q 序列剩下位置的数字
for(int i = 0; i < n; i ++ ){
int u = v[i].second;
if(p[u] == 0){
while(cp[r1]) r1 --;
if(r1 > q[u]){
// 是否可以合法放入
cout << "NO" << endl;
return ;
}
p[u] = r1, cp[r1] ++, r1 --;
}
else{
while(cq[r2]) r2 --;
if(r2 > p[u]){
cout << "NO" << endl;
return;
}
q[u] = r2, cq[r2] ++, r2 --;
}
}
for(int i = 1; i <= n; i ++ ){
// 判断q序列数字是否都出现一次
if(cq[i] != 1){
cout << "NO" << endl;
return ;
}
}
out();
}
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t;
cin >> t;
while(t -- ) solve();
}
D. Lucky Permutation
思路分析:
交换排序的最小操作步骤
代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void solve(){
int n, cnt = 0; // cnt 所需要的操作步骤
cin >> n;
vector<int> v(n + 1), cv(n + 1);
for(int i = 0; i < n; i ++ ){
cin >> v[i], v[i] --;
}
int ind = 1;
for(int i = 0; i < n; i ++ ){
// 找到所有的环,对同一个环标记
if(cv[v[i]]) continue;
int j = v[i];
while(cv[j] == 0){
cv[j] = ind;
j = v[j];
cnt ++;
}
cnt --, ind ++;
}
for(int i = 0; i < n - 1; i ++ ){
// 是否存在相邻数字在一个环内
if(cv[i] == cv[i + 1]){
cout << cnt - 1 << endl;
return ;
}
}
cout << cnt + 1 << endl;
return ;
}
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t;
cin >> t;
while(t -- ) solve();
}
E. Partial Sorting
思路分析:
代码:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 3e6 + 10;
LL fac[N], inv[N], n, mod;
qmi(LL a, LL b, LL mod){
LL sum = 1;
while(b){
if(b & 1) sum = sum * a % mod;
b >>= 1;
a = a * a % mod;
}
return sum;
}
LL C(LL n, LL k){
return fac[n] * inv[k] % mod * inv[n - k] % mod;
}
void init(){
// 预处理阶乘和其对应逆元
fac[0] = inv[0] = 1;
for(int i = 1; i <= 3000000; i ++ ){
fac[i] = fac[i - 1] * i % mod;
}
inv[3000000] = qmi(fac[3000000], mod - 2, mod);
for(int i = 3000000; i > 0; i -- ){
inv[i - 1] = inv[i] * i % mod;
}
}
int main(){
cin >> n >> mod;
init();
LL ans[4];
ans[0] = 1; // 以下计算操作次数 f(p) == 0
ans[1] = (fac[2 * n] * 2 % mod - fac[n]) % mod; // 以下计算操作次数 f(p) <= 1
ans[1] = (ans[1] - ans[0] + mod) % mod; // f(p) == 1
ans[2] = fac[2 * n] * fac[n] % mod * C(2 * n, n) % mod * 2 % mod; // 以下计算操作次数 f(p) <= 2
LL sum = 0;
for(int i = 0; i <= n; i ++ ){
LL sub = 1;
sub = sub * C(n, i) % mod * C(n, n - i) % mod * C(2 * n - i, n) % mod;
sub = sub * fac[n] % mod * fac[n] % mod * fac[n] % mod;
sum = (sum + sub) % mod;
}
ans[2] = ans[2] - sum;
ans[2] = (ans[2] - ans[0] - ans[1] + mod) % mod;; // f(p) == 2
ans[3] = fac[3 * n]; // 以下计算操作次数 f(p) <= 3
ans[3] = (ans[3] - ans[0] - ans[1] - ans[2] + 2 * mod) % mod;; // f(p) == 3
LL result = (ans[1] + 2 * ans[2] + 3 * ans[3]) % mod;
cout << result << endl;
}