题目链接

题意:

  给出一个长度为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. Ceisum官方教程2 -- 项目实例(workshop)

    原文地址:https://cesiumjs.org/tutorials/Cesium-Workshop/ 概述 我们很高兴欢迎你加入Cesium社区!为了让你能基于Cesium开发自己的3d 地图项目 ...

  2. 使用em为单位制作两列弹性布局

    一.DIV布局按照定位的方法分为:浮动方法(float),坐标定位方法(position),还有就是两者相结合的方法. 二.DIV布局按照定义单位的不同可分为:固定宽度布局.流体布局.弹性布局和混合布 ...

  3. Python学习之函数(多层函数)、re模块的正则匹配--计算复杂加减乘除

    头疼,其实这个程序在我看的视频当中是当做re模块的运用来进行测试的,而到了我这里就成了简化版的了,因为我实在是做吐了,恕小弟无能,只能做简化版的.为何说是简化版呢,因为要求是给的计算式是多层嵌套的小括 ...

  4. Leetcode114. Flatten Binary Tree to Linked List二叉树展开为链表

    给定一个二叉树,原地将它展开为链表. 例如,给定二叉树 1 / \ 2 5 / \ \ 3 4 6 将其展开为: 1 \ 2 \ 3 \ 4 \ 5 \ 6 class Solution { publ ...

  5. Redis源码解析:30发布和订阅

    Redis的发布与订阅功能,由SUBSCRIBE,PSUBSCRIBE,UNSUBSCRIBE,PUNSUBSCRIBE,以及PUBLISH等命令实现. 通过执行SUBSCRIBE命令,客户端可以订阅 ...

  6. [转]文件file属性详解

    不能直接访问用户计算机中的文件,一直都是Web应用开发中的一大障碍.2000年以前,处理文件的唯一方式就是在表单中加入<input type="file">字段,仅此而 ...

  7. Java review-design pattern

    Design Patterns (Factory, Abstract Factory, singleton, DAO, Proxy): 1. Factory: In Factory pattern, ...

  8. db link的查看创建与删除 1

    1.查看dblink select owner,object_name from dba_objects where object_type='DATABASE LINK'; 或者 select * ...

  9. eclipse2018整合tomcat9

    eclipse2018整合tomcat9 选择 Windows --> preferences --> server --> runtime environmen:点击“add”按钮 ...

  10. Kth Minimum Clique

    Kth Minimum Clique 题目描述 Given a vertex-weighted graph with N vertices, find out the K-th minimum wei ...