Permutation Cycle CodeForces - 932C(构造环)

For a permutation P[1… N] of integers from 1 to N, function f is defined as follows:

Let g(i) be the minimum positive integer j such that f(i, j) = i. We can show such j always exists.

For given N, A, B, find a permutation P of integers from 1 to N such that for 1 ≤ i ≤ N, g(i) equals either A or B.

Input
The only line contains three integers N, A, B (1 ≤ N ≤ 106, 1 ≤ A, B ≤ N).

Output
If no such permutation exists, output -1. Otherwise, output a permutation of integers from 1 to N.

Examples
Input
9 2 5
Output
6 5 8 3 4 1 9 2 7
Input
3 2 1
Output
1 2 3
Note
In the first example, g(1) = g(6) = g(7) = g(9) = 2 and g(2) = g(3) = g(4) = g(5) = g(8) = 5

In the second example, g(1) = g(2) = g(3) = 1

题意: 给出一个递归函数f(i,j),g(i) 为 f(i,j) = i时的最小j。求一个全排列使得g(i)要么为A,要么为B;
思路: 翻译一下题目,找x个A边环和y个B边环,使得xA + yB = n。方程无解则为-1。方程有解的情况,就直接构造环即可。构造的过程有技巧,假设A个边,那么把第一个数放到第A个,其他数往前移动即可。因为每一个点的值指向下一个点,目的是让这个点进过A次指向回到自己。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int main()
{
    int n,a,b;scanf("%d%d%d",&n,&a,&b);//n = x*a + y*b;
    int x = 0,y = 0,flag = 0;
    for(int i = 0;i * a <= n;i++)
    {
        int j = n - i * a;
        if(j % b == 0)
        {
            x = i;
            y = j / b;
            flag = 1;
            break;
        }
    }
    if(!flag)printf("-1\n");
    else
    {
        int cnt = 1;
        int last = cnt;
        for(int i = 1;i <= x;i++)
        {
            for(int j = 1;j < a;j++)
            {
                printf("%d ",++cnt);
            }
            printf("%d ",last);
            cnt++;
            last = cnt;
        }
        for(int i = 1;i <= y;i++)
        {
            for(int j = 1;j < b;j++)
            {
                printf("%d ",++cnt);
            }
            printf("%d ",last);
            cnt++;
            last = cnt;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值