题目链接

题意:

  给出一个长度为n(n<=10^5)的数组a,  数组a是数字1到n的一种排列(打乱顺序).

  每次可以选择两个数(不同)进行交换, 但是交换的条件是被选择的两个数的下标之差加1应该是一个素数.

思路:

  比赛的时候WA到爆..好弱, 思路基本都是对的, 贪心. 用数组pos[i]来维护值i在数组中的位置.

  对于第i个数, 如果 pos[i]-i+1是素数,那么就直接交换.否则, 需要多次交换来使得a[i] = i;

  采用贪心策略, 从i+1开始枚举是否可以与pos[i]进行交换, 这里交换的次数不会很多,

  因为只有当m!+2, m!+3, ......., m!+m时会存在m-1个连续的合数, 而n<=10^5, 所以m <=8

  所以交换的次数不会超过5次.

附上代码:

 /*************************************************************************
> File Name: C.cpp
> Author: Stomach_ache
> Mail: sudaweitong@gmail.com
> Created Time: 2014年05月15日 星期四 23时51分15秒
> Propose:
************************************************************************/ #include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <fstream>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; bool is_prime[];
int a[], pos[]; // hold the index of the value of i
typedef pair<int, int> pii;
vector<pii> ans; // keep each move... void
init() {
memset(is_prime, true, sizeof(is_prime));
is_prime[] = false;
for (int i = ; i < ; i++) {
if (is_prime[i]) {
for (int j = i*i; j < ; j += i) {
is_prime[j] = false;
}
}
}
return ;
} int
main(void) {
init();
int n;
scanf("%d", &n);
for (int i = ; i <= n; i++) {
scanf("%d", a + i);
pos[a[i]] = i;
}
for (int i = ; i <= n; i++) {
if (i == a[i]) continue;
if (is_prime[pos[i]-i+]) {
swap(a[i], a[pos[i]]);
ans.push_back(pii(pos[i], i));
pos[a[pos[i]]] = pos[i];
pos[i] = i;
} else {
// distance from index i to pos[i]
int d = pos[i] - i;
// in other words, a[i] will be equal to i when d equals 0
while (d) {
for (int k = d; k >= ; k--) {
if (is_prime[k+]) {
// from index of i+d-k to index of pos[i]
swap(a[i+d-k], a[pos[i]]);
// push to ans
ans.push_back(pii(i+d-k, pos[i]));
// update pos[]
pos[a[pos[i]]] = pos[i];
pos[i] = i+d-k;
// update d
d -= k;
break;
}
}
}
}
}
// for (int i = 1; i <= 10; i++) {
// cout << a[i] << ' ';
// }
// cout << endl;
int len = ans.size();
printf("%d\n", len);
for (int i = ; i < len; i++) {
if (ans[i].first > ans[i].second) {
swap(ans[i].first, ans[i].second);
}
printf("%d %d\n", ans[i].first, ans[i].second);
} return ;
}

   

Codeforces 432C的更多相关文章

  1. CodeForces 432C Prime Swaps

    Description You have an array a[1], a[2], ..., a[n], containing distinct integers from 1 to n. Your ...

  2. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  3. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  4. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  5. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  6. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  7. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  8. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  9. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

随机推荐

  1. xml文件节点读取时,selectNodes总是在根节点下查找的问题

    参考:https://yq.aliyun.com/articles/39543 SAXReader reader = new SAXReader();Document document = reade ...

  2. 扫描线矩形周长的并 POJ1177

    //扫描线矩形周长的并 POJ1177 // 我是按x轴 #include <iostream> #include <cstdio> #include <cstdlib& ...

  3. iscroll的滑动效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. JavaScript中[]+[] 、[]+{}、{}+[]、{}+{}的结果分析

    看到这样一个问题:{} + [] 的结果是多少? 一脸懵逼.. 于是在chrome控制台运行 {} + [] 和用 console.log({} + []) 输出,发现结果不一样.. 于是,把各种可能 ...

  5. stackless 安装

    1.下载源码 https://bitbucket.org/stackless-dev/stackless/wiki/Download 2.编译.安装.路径生效 apt-get install libr ...

  6. ES6 promise 封装http请求

    今天研究了一下同事封装的http请求,用的是promise. 大结构是: const __fetch = (url, data = {}, config = {}) => { let param ...

  7. JAVA短信验证码 工具类

    MsgCodeUtil.java package com.hg.util; import com.soyea.enums.ResultEnum; import com.soyea.exception. ...

  8. 计蒜客 Red Black Tree(树形DP)

    You are given a rooted tree with n nodes. The nodes are numbered 1..n. The root is node 1, and m of ...

  9. ubuntu和win10设置双显示器

    ubuntu:最右上角那个图标,点开找到系统设置,系统设置中找到“显示”中,在其中可以调节双屏显示或者只显示一个屏,图等会补... win10:现在是ubuntu系统所以操作忘记了写不出来,等下换系统 ...

  10. 【洛谷P3131】 【USACO16JAN】子共七

    P3131 [USACO16JAN]子共七Subsequences Summing to Sevens 题目描述 Farmer John's cows are standing in a row, a ...