Codeforces Round #246 (Div. 2)(C)数学,思维

来源:互联网 发布:足球分析软件下载 编辑:程序博客网 时间:2024/06/08 14:54

C. Prime Swaps
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You have an array a[1], a[2], ..., a[n], containing distinct integers from 1 to n. Your task is to sort this array in increasing order with the following operation (you may need to apply it multiple times):

  • choose two indexes, i and j (1 ≤ i < j ≤ n(j - i + 1) is a prime number);
  • swap the elements on positions i and j; in other words, you are allowed to apply the following sequence of assignments:tmp = a[i], a[i] = a[j], a[j] = tmp (tmp is a temporary variable).

You do not need to minimize the number of used operations. However, you need to make sure that there are at most 5n operations.

Input

The first line contains integer n (1 ≤ n ≤ 105). The next line contains n distinct integers a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ n).

Output

In the first line, print integer k (0 ≤ k ≤ 5n) — the number of used operations. Next, print the operations. Each operation must be printed as "i j" (1 ≤ i < j ≤ n(j - i + 1) is a prime).

If there are multiple answers, you can print any of them.

Sample test(s)
input
33 2 1
output
11 3
input
21 2
output
0
input
44 2 3 1
output
32 41 22 4



题意:给你(1---n),n个数字。要求你将数字排序为升序,数字交换swap(a[i],a[j]):满足数组下标(j-i+1)必须是素数才能进行交换,而且总交换次数不能超过5*n次



题解:看了这一题就剩下一个大大的懵逼。。。。。。。,这里只要这样处理:我们先记录所有的数字的下标,每次我们从最小的数字开始排序,如果当前的数字不在排序位,那么我们把他交换到最接近的排序位的地方,至于5*n次,不知道怎么去证明,官方题解说:

It could be proved that such algorithm makes less than 4n swaps (for example, by implementing the algorithm)

可以证明出不会超过4*n次


素数直接上晒素数模板就可以了



#include <set>  #include <map>  #include <list>   #include <cmath>   #include <queue>   #include <vector>  #include <cstdio>   #include <string>   #include <cstring>  #include <iomanip>   #include <iostream>   #include <sstream>  #include <algorithm>  #include <utility>#define LL long long using namespace std;  #define N 100005 #define inf 0x3f3f3f3fint a[N];bool prime[N+5];   int pos[N];void prime_table()  {      int m = sqrt(N + 0.5);      memset(prime, false, sizeof(prime));      for (int i = 2; i <= m; i++)      {          if (!prime[i])          {              for (int j = i*i; j <= N; j += i)              {                  prime[j] = true;              }          }      }  prime[1]=true;}vector<pair<int,int>>result;int main()  {  #ifdef CDZSC    freopen("i.txt","r",stdin);  #endif  prime_table();int n;while(~scanf("%d",&n)){result.clear();for(int i=1;i<=n;i++){scanf("%d",&a[i]);pos[a[i]]=i;}for(int i=1;i<=n;i++){int now=pos[i];while(now>i){int tmp=i;while(prime[now- tmp+1])tmp++;result.push_back(make_pair(tmp,now));pos[a[now]]=tmp;pos[a[tmp]]=now;swap(a[now],a[tmp]);now=tmp;}}printf("%d\n",result.size());for(int i=0;i<result.size();i++){printf("%d %d\n",result[i].first,result[i].second);}}return 0;}




0 0
原创粉丝点击