Prime Swaps

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82662#problem/F

题目大意:有n个数的序列,通过交换使其变得有序,交换的原则是每次交换的数字ai和aj,(j-i+1)必须是质数,要求在5n步内完成。

解题思路:完全没懂这个题,看网上都说用哥德巴赫猜想,但是
“由猜想可得,每个大于等于5的数都可以有三个质数相加获得,而2,3都是质数,4=2+2,所以所有大于等于2的数都可以用质数表示。所以无论i,j多少,每次交换i,j都可以在三步之内获得”这个我觉得只能证明能在5n步内完成交换吧。。。

首先,肯定是需要对质数进行判断的,0和1不是质数
接着,如果a[i]的值不是其对应的i的位置,那么执行交换处理,处理a[i]和i的值:如果i>a[i],swap;从较大的数开始向较小数处理,如果是k-x+1质数,则:交换a[k]和a[x]的值,把本次交换记录下来,再执行i和y的处理。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;

#define N 100005

int l[N<<2], r[N<<2], a[N];
bool prime[N];
int ans, n;

void primeNumber()
{
    memset(prime, true, sizeof(prime));
    prime[0] = prime[1] = false;
    for(int i = 2; i < N; i++)
    {
        if(prime[i])
        {
            for(int j = i+i; j < N; j+=i)
                prime[j] = false;
        }
    }
}

void exchang(int x, int y)
{
    if(x > y)
        swap(x, y);
    for(int i = y; i > x; i--)
    {
        if(prime[i-x+1])
        {
            swap(a[i],a[x]);
            l[ans] = x;
            r[ans++] = i;
            exchang(i,y);
            break;
        }
    }
}

int main()
{
    primeNumber();
    while(cin >> n)
    {
        ans = 0;
        for(int i = 1; i <= n; i++)
            cin >> a[i];
        for(int i = 1; i <= n; i++)
            while(i!=a[i])
                exchang(i,a[i]);
        cout << ans << endl;
        for(int i = 0; i < ans; i++)
            cout << l[i] << " " << r[i] << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值