zoukankan      html  css  js  c++  java
  • 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;
    } 
  • 相关阅读:
    单元测试的必要性
    【C++ STL】Queue
    【C++ STL】Stack
    【C++ STL】容器的选择
    【C++ STL】Map和Multimap
    [Effective JavaScript 笔记]第19条:熟练掌握高阶函数
    [Effective JavaScript 笔记]第18条:理解函数调用、方法调用及构造函数调用之间的不同
    node实现rar格式压缩
    [Effective JavaScript 笔记]第2章:变量作用域--个人总结
    [Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用
  • 原文地址:https://www.cnblogs.com/NJUWZ/p/7101166.html
Copyright © 2011-2022 走看看