A. Wonderful Permutation
time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output
Problem Statement
You are given a permutation p 1 , p 2 , … , p n p_1,p_2,…,p_n p1,p2,…,pn of length n and a positive integer k ≤ n k≤n k≤n.
In one operation you can choose two indices i i i and j j j ( 1 ≤ i < j ≤ n ) (1≤i<j≤n) (1≤i<j≤n) and swap p i p_i pi with p j p_j pj.
Find the minimum number of operations needed to make the sum p 1 + p 2 + … + p k p_1+p_2+…+p_k p1+p2+…+pk as small as possible.
A permutation is an array consisting of n n n distinct integers from 1 to n n n in arbitrary order. For example, [ 2 , 3 , 1 , 5 , 4 ] [2,3,1,5,4] [2,3,1,5,4] is a permutation, but [ 1 , 2 , 2 ] [1,2,2] [1,2,2] is not a permutation ( 2 2 2 appears twice in the array) and [ 1 , 3 , 4 ] [1,3,4] [1,3,4] is also not a permutation ( n = 3 n=3 n=3 but there is 4 4 4 in the array).
题面翻译
给出一个长度为 n n n的排列 p 1 , p 2 , . . . , p n p_1,p_2,...,p_n p1,p2,...,pn和一个正整数 k k k。
在每一次操作中,你可以交换任意的 a i , a j ( 1 ≤ i , j ≤ n ) a_i,a_j(1 \le i,j \le n) ai,aj(1≤i,j≤n)。
求当 p 1 + p 2 + . . . + p k p_1+p_2+...+p_k p1+p2+...+pk最小时,最少的操作次数。
定义:排列是指有 1 1 1至 n n n组成的任意排序。例如, [ 2 , 3 , 1 , 5 , 4 ] [2,3,1,5,4] [2,3,1,5,4]是一个排列,但 [ 1 , 2 , 2 ] [1,2,2] [1,2,2]不是排列( 2 2 2在数组中出现两次), [ 1 , 3 , 4 ] [1,3,4] [1,3,4]也不是排列( n = 3 n=3 n=3但 4 4 4也在数组中)。
Input
Each test contains multiple test cases. The first line contains the number of test cases t ( 1 ≤ t ≤ 100 ) t (1≤t≤100) t(1≤t≤100). Description of the test cases follows.
The first line of each test case contains two integers n n n and k ( 1 ≤ k ≤ n ≤ 100 ) k (1≤k≤n≤100) k(1≤k≤n≤100).
The second line of each test case contains n n n integers p 1 , p 2 , … , p n ( 1 ≤ p i ≤ n ) p_1,p_2,…,p_n (1≤p_i≤n) p1,p2,…,pn(1≤pi≤n). It is guaranteed that the given numbers form a permutation of length n n n.
Output
For each test case print one integer — the minimum number of operations needed to make the sum p 1 + p 2 + … + p k p_1+p_2+…+p_k p1+p2+…+pk as small as possible.
Example
input
4
3 1
2 3 1
3 3
1 2 3
4 2
3 4 1 2
1 1
1
output
1
0
2
0
Note
In the first test case, the value of p 1 + p 2 + … + p k p_1+p_2+…+p_k p1+p2+…+pk is initially equal to 2 2 2, but the smallest possible value is 1 1 1. You can achieve it by swapping p 1 p_1 p1 with p 3 p_3 p3, resulting in the permutation [ 1 , 3 , 2 ] [1,3,2] [1,3,2].
In the second test case, the sum is already as small as possible, so the answer is 0 0 0.
题解部分
既然这个数组是一个排列,那最小的 k k k个数一定是 1 , 2 , . . . , k 1,2,...,k 1,2,...,k,所以我们只需要看 p 1 , p 2 , . . . , p k p_1,p_2,...,p_k p1,p2,...,pk中有多少个大于 k k k的数,就是要交换掉的数。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int MAXN = 100 + 5;
int T, n, k, a[MAXN], minn, minp, cnt;
int main () {
scanf ("%d", &T);
while (T --) {
scanf ("%d %d", &n, &k);
for (int i = 1; i <= n; i ++) {
scanf ("%d", &a[i]);
}
cnt = 0;
for (int i = 1; i <= k; i ++) {
if (a[i] <= k) {
cnt ++;
}
}
printf ("%d\n", k - cnt);
}
return 0;
}
B. Woeful Permutation
time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output
Problem Statement
You are given a positive integer n n n.
Find any permutation p p p of length n n n such that the sum l c m ( 1 , p 1 ) + l c m ( 2 , p 2 ) + … + l c m ( n , p n ) lcm(1,p_1)+lcm(2,p_2)+…+lcm(n,p_n) lcm(1,p1)+lcm(2,p2)+…+lcm(n,pn) is as large as possible.
Here l c m ( x , y ) lcm(x,y) lcm(x,y) denotes the least common multiple (LCM) of integers x x x and y y y.
A permutation is an array consisting of n n n distinct integers from 1 1 1 to n n n in arbitrary order. For example, [ 2 , 3 , 1 , 5 , 4 ] [2,3,1,5,4] [2,3,1,5,4] is a permutation, but [ 1 , 2 , 2 ] [1,2,2] [1,2,2] is not a permutation ( 2 2 2 appears twice in the array) and [ 1 , 3 , 4 ] [1,3,4] [1,3,4] is also not a permutation ( n = 3 n=3 n=3 but there is 4 4 4 in the array).
题面翻译
给出一个数 n n n,求出长度为 n n n的排列 p p p使得 l c m ( 1 , p 1 ) + l c m ( 2 , p 2 ) + … + l c m ( n , p n ) lcm(1,p_1)+lcm(2,p_2)+…+lcm(n,p_n) lcm(1,p1)+lcm(2,p2)+…+lcm(n,pn)最大,若答案不唯一,随机输出一组。
Input
Each test contains multiple test cases. The first line contains the number of test cases t ( 1 ≤ t ≤ 1000 ) t (1≤t≤1000) t(1≤t≤1000). Description of the test cases follows.
The only line for each test case contains a single integer n ( 1 ≤ n ≤ 1 0 5 ) n (1≤n≤10^5) n(1≤n≤105).
It is guaranteed that the sum of n n n over all test cases does not exceed 1 0 5 10^5 105.
Output
For each test case print n integers p 1 , p 2 , … , p n p_1, p_2, …, p_n p1,p2,…,pn — the permutation with the maximum possible value of l c m ( 1 , p 1 ) + l c m ( 2 , p 2 ) + … + l c m ( n , p n ) lcm(1,p_1)+lcm(2,p_2)+…+lcm(n,p_n) lcm(1,p1)+lcm(2,p2)+…+lcm(n,pn).
If there are multiple answers, print any of them.
Example
input
2
1
2
output
1
2 1
Note
For n = 1 n=1 n=1, there is only one permutation, so the answer is [ 1 ] [1] [1].
For n = 2 n=2 n=2, there are two permutations:
[ 1 , 2 ] [1,2] [1,2] — the sum is l c m ( 1 , 1 ) + l c m ( 2 , 2 ) = 1 + 2 = 3 lcm(1,1)+lcm(2,2)=1+2=3 lcm(1,1)+lcm(2,2)=1+2=3.
[ 2 , 1 ] [2,1] [2,1] — the sum is l c m ( 1 , 2 ) + l c m ( 2 , 1 ) = 2 + 2 = 4 lcm(1,2)+lcm(2,1)=2+2=4 lcm(1,2)+lcm(2,1)=2+2=4.
题解部分
众所周知,相邻的两个数互质,也就是说 gcd ( k , k + 1 ) = 1 \gcd(k,k+1)=1 gcd(k,k+1)=1。
而且还有这样一个性质: gcd ( a , b ) × l c m ( a , b ) = a b \gcd(a,b) \times lcm(a,b)=ab gcd(a,b)×lcm(a,b)=ab,
∴ l c m ( k , k + 1 ) = k 2 + k \therefore lcm(k,k+1)=k^2+k ∴lcm(k,k+1)=k2+k
那么,我们尽量让 k k k越大越好,所以相邻两个数就可以这样求 l c m lcm lcm,使得代价最小且乘积最大。
先来讨论一下 k k k为奇数的情况:
我们只用比较下面两种情况中的较大值:
i i i | 1 1 1 | 2 2 2 | 3 3 3 | 4 4 4 | 5 5 5 | 6 6 6 | . . . ... ... | k − 2 k-2 k−2 | k − 1 k-1 k−1 | k k k |
---|---|---|---|---|---|---|---|---|---|---|
情况 1 1 1 | 2 2 2 | 1 1 1 | 4 4 4 | 3 3 3 | 6 6 6 | 5 5 5 | . . . ... ... | k − 1 k-1 k−1 | k − 2 k-2 k−2 | k k k |
情况 2 2 2 | 1 1 1 | 3 3 3 | 2 2 2 | 5 5 5 | 4 4 4 | 7 7 7 | . . . ... ... | k − 3 k-3 k−3 | k k k | k − 1 k-1 k−1 |
情况 1 1 1是从前往后两两分成一组,最后单出来一个 k k k,情况 2 2 2是从后往前两两分成一组,最后单出来一个 1 1 1。
那么情况 1 1 1的结果为 1 × 2 + 3 × 4 + 5 × 6 + . . . + ( k − 2 ) ( k − 1 ) + k 1 \times 2+3 \times 4+5 \times 6+...+(k-2)(k-1)+k 1×2+3×4+5×6+...+(k−2)(k−1)+k,
情况 2 2 2的结果为 1 + 2 × 3 + 4 × 5 + 6 × 7 + . . . + ( k − 1 ) ⋅ k 1+2 \times 3+4 \times 5+6 \times 7+...+(k-1) \cdot k 1+2×3+4×5+6×7+...+(k−1)⋅k。
要比较两式的结果,用的方法是两式相减。
① ① ①式 − ② -② −②式得: − 2 ( 2 + 4 + 6 + . . . + k − 1 ) + k − 1 -2(2+4+6+...+k-1)+k-1 −2(2+4+6+...+k−1)+k−1
若 k − 1 > 2 ( 2 + 4 + 6 + . . . + k − 1 ) k-1>2(2+4+6+...+k-1) k−1>2(2+4+6+...+k−1),则原式为正,否则为非正。
我们就解这个不等式,
k − 1 > 4 ( 1 + 2 + 3 + . . . + k − 1 2 ) k-1>4(1+2+3+...+ \frac{k-1}{2}) k−1>4(1+2+3+...+2k−1)
k − 1 > 4 × ( 1 + k − 1 2 ) ⋅ k − 1 2 2 k-1>4 \times \frac{(1+\frac{k-1}{2}) \cdot \frac{k-1}{2}}{2} k−1>4×2(1+2k−1)⋅2k−1
k − 1 > ( k − 1 ) ( 1 + k − 1 2 ) k-1>(k-1)(1+\frac{k-1}{2}) k−1>(k−1)(1+2k−1)
因为题目条件中 k ≤ 1 k \le 1 k≤1,所以 k − 1 ≤ 0 k-1 \le 0 k−1≤0,当 k − 1 = 0 k-1=0 k−1=0时无意义,当 k > 1 k>1 k>1时:
1 + k − 1 2 < 1 1+\frac{k-1}{2}<1 1+2k−1<1
k − 1 2 < 0 \frac{k-1}{2}<0 2k−1<0
k < 1 k<1 k<1
这明显与题目不符,所以若满足题目条件, k ≤ 1 k \le 1 k≤1,这时,原式为负,所以情况 2 2 2更优。
再来讨论一下 k k k为偶数的情况,这只有一种情况,即:
i i i | 1 1 1 | 2 2 2 | 3 3 3 | 4 4 4 | 5 5 5 | 6 6 6 | . . . ... ... | k − 1 k-1 k−1 | k k k |
---|---|---|---|---|---|---|---|---|---|
情况 | 2 2 2 | 1 1 1 | 4 4 4 | 3 3 3 | 6 6 6 | 5 5 5 | . . . ... ... | k k k | k − 1 k-1 k−1 |
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int T, n;
int main () {
scanf ("%d", &T);
while (T --) {
scanf ("%d", &n);
if (n % 2 == 1) {
printf ("1 ");
for (int i = 2; i <= n; i ++) {
if (i % 2) {
printf ("%d ", i - 1);
} else {
printf ("%d ", i + 1);
}
}
} else {
for (int i = 1; i <= n; i ++) {
if (i % 2) {
printf ("%d ", i + 1);
} else {
printf ("%d ", i - 1);
}
}
}
printf ("\n");
}
return 0;
}
C. Sort Zero
time limit per test:1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output
Problem Statement
You are given an array of n n n positive integers a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,…,an.
In one operation you do the following:
Choose any integer x x x.
For all i i i such that a i = x a_i=x ai=x, do a i : = 0 a_i:=0 ai:=0 (assign 0 0 0 to a i a_i ai).
Find the minimum number of operations required to sort the array in non-decreasing order.
Input
Each test contains multiple test cases. The first line contains the number of test cases t ( 1 ≤ t ≤ 1 0 4 ) t (1≤t≤10^4) t(1≤t≤104). Description of the test cases follows.
The first line of each test case contains a single integer n ( 1 ≤ n ≤ 1 0 5 ) n (1≤n≤10^5) n(1≤n≤105).
The second line of each test case contains n n n positive integers a 1 , a 2 , … , a n ( 1 ≤ a i ≤ n ) a_1,a_2,…,a_n (1≤a_i≤n) a1,a2,…,an(1≤ai≤n).
It is guaranteed that the sum of n n n over all test cases does not exceed 1 0 5 10_5 105.
Output
For each test case print one integer — the minimum number of operations required to sort the array in non-decreasing order.
题面翻译
给出一个长度为 n n n的数组,你每次要进行以下操作:
任意取一个数 x x x,并将数组中所有 a i = x a_i=x ai=x的 a i a_i ai修改为 0 0 0。
求最小需要修改多少次,才能是整个数组成为一个非下降数列。
Example
input
5
3
3 3 2
4
1 3 1 3
5
4 1 5 3 2
4
2 4 1 2
1
1
output
1
2
4
3
0
Note
In the first test case, you can choose x = 3 x=3 x=3 for the operation, the resulting array is [ 0 , 0 , 2 ] [0,0,2] [0,0,2].
In the second test case, you can choose x = 1 x=1 x=1 for the first operation and x = 3 x=3 x=3 for the second operation, the resulting array is [ 0 , 0 , 0 , 0 ] [0,0,0,0] [0,0,0,0].
题解部分
模拟法。用一个while
循环模拟筛数的过程。
#include <cstdio>
#include <set>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int MAXN = 1e5 + 5;
int T, n, a[MAXN];
set <int> s;
int main () {
scanf ("%d", &T);
while (T --) {
scanf ("%d", &n);
for (int i = 1; i <= n; i ++) {
scanf ("%d", &a[i]);
}
int cnt = 0;
bool flag = 1;
while (flag) {
flag = 0;
for (int i = n; i >= 1; i --) {
if (a[i - 1] > a[i]) {
s.clear();
for (int j = i - 1; j >= 1; j --) {
if (a[j] == 0) {
break;
}
s.insert(a[j]);
}
cnt += s.size();//优化,第i个点不满足,a[i]=0,因为1<=a[i],所以i点之前的数>=0,所以前面的非0数同样不满足
for (int j = 1; j <= n; j ++) {
if (s.count(a[j]) != 0) {
a[j] = 0;
}
}
flag = 1;
break;
}
}
}
printf ("%d\n", cnt);
}
return 0;
}