Codeforces 818B Permutation Game

首先看一下题目
B. Permutation Game
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

n children are standing in a circle and playing a game. Children's numbers in clockwise order form a permutation a1, a2, ..., an of lengthn. It is an integer sequence such that each integer from 1 to n appears exactly once in it.

The game consists of m steps. On each step the current leader with index i counts out ai people in clockwise order, starting from the next person. The last one to be pointed at by the leader becomes the new leader.

You are given numbers l1, l2, ..., lm — indices of leaders in the beginning of each step. Child with number l1 is the first leader in the game.

Write a program which will restore a possible permutation a1, a2, ..., an. If there are multiple solutions then print any of them. If there is no solution then print -1.

Input

The first line contains two integer numbers nm (1 ≤ n, m ≤ 100).

The second line contains m integer numbers l1, l2, ..., lm (1 ≤ li ≤ n) — indices of leaders in the beginning of each step.

Output

Print such permutation of n numbers a1, a2, ..., an that leaders in the game will be exactly l1, l2, ..., lm if all the rules are followed. If there are multiple solutions print any of them.

If there is no permutation which satisfies all described conditions print -1.

Examples
input
4 5
2 3 1 4 4
output
3 1 2 4 
input
3 3
3 1 2
output
-1
 
题Note

Let's follow leadership in the first example:

  • Child 2 starts.
  • Leadership goes from 2 to 2 + a2 = 3.
  • Leadership goes from 3 to 3 + a3 = 5. As it's greater than 4, it's going in a circle to 1.
  • Leadership goes from 1 to 1 + a1 = 4.
  • Leadership goes from 4 to 4 + a4 = 8. Thus in circle it still remains at 4.

这题目我理解了好久,题目是说,有n个孩子围成一个圈,他们每个人分别有一个index和序号,index是从1-n,序号是从a1到an,并且恰好满足它们是1-n的一个全排列。

游戏分成m步,从第1步开始数。第i步的时候,当前的leader有一个index,我们记做k,他需要从他下一个人开始数出ak个人,然后再下一个人成为新的leader。我们需要给出m个数字,从l1到lm。对于第一个leader,我们需要找出某个ai,使得l1=ai,此时第i个孩子是第一个leader。

我们的目标是给出m个数字,使得所有的规则都成立。

---------------------------------------------------分割线------------------------------------------------------------------------------------------------------------------------------------------------------------------

之前的理解有点扯。。。我在晚上终于理解了。。

 

题目给定了leader index序列,要我们求a[n]序列,显然由leader index 的变化,我们是可以轻易求出a[leader index]的。。。但是这题目的描述确实不行,也确实有很多人吐槽题意。。。

最后贴一下代码

#include <iostream>

using namespace std;

const int maxn = 105;

int used[maxn];
int l[maxn];
int a[maxn];

int main() {
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < m; i++) {
        cin >> l[i];
    }
    for(int i = 1; i < m; i++) {
        int delta = l[i] - l[i-1];
        if(delta <= 0) {
            delta = n + delta;
        }
        if(l[i-1] != used[delta] && used[delta] != 0) {
            cout << "-1" << endl;
            return 0;
        }
        a[l[i-1]] = delta;
        used[delta] = l[i-1];
    }
    if(a[1] == 0) {
        for(int i = 1; i < maxn; i++) {
            if(!used[i]) {
                a[1] = i;
                used[i] = true;
                break;
            }
        }
    }
    cout << a[1];
    for(int i = 2; i <= n; i++) {
        if(a[i] == 0) {
            for(int j = 1; j < maxn; j++) {
                if(!used[j]) {
                    a[i] = j;
                    used[j] = true;
                    break;
                } 
            } 
        }
        cout << " " << a[i];
    }
    cout << endl;
    return 0;
} 

 我今天又看了一下cf,发现自己居然WA了。不过确实是因为代码写错了。。有一些情况没考虑到。如下是正确代码

#include <iostream>

using namespace std;

const int maxn = 105;

int used[maxn];
int l[maxn];
int a[maxn];

int main() {
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < m; i++) {
        cin >> l[i];
    }
    for(int i = 1; i < m; i++) { 
        int delta = l[i] - l[i-1];
        if(delta <= 0) {
            delta = n + delta;
        }
        if(a[l[i-1]] == 0) {
            if(used[delta]) {
                cout << "-1" << endl;
                return 0;
            }
            a[l[i-1]] = delta;
            used[delta] = a[l[i-1]];
            continue;
        } 
        if(delta != a[l[i-1]]) {
            cout << "-1" << endl;
            return 0;
        }
        
    }
    
    for(int i = 1; i <= n; i++) {
        if(!a[i]) {
            for(int j = 1; j <= n; j++) {
                if(!used[j]) {
                    used[j] = true;
                    a[i] = j;
                    break;
                }
            }
        }
    }
    cout << a[1];
    for(int i = 2; i <= n; i++) {
        cout << " " << a[i];
    }
    cout << endl;
    return 0;
} 

 

转载于:https://www.cnblogs.com/NJUWZ/p/7101166.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值