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;
    } 
  • 相关阅读:
    天猫和淘宝有什么区别
    Oracle (内连接)
    共享受限资源,Brian的同步规则
    后台线程,优先级,sleep,yield
    runnable和thread的区别
    Oracle 左连接、右连接、全外连接、(+)号作用、inner join(等值连接) (转载)
    oracle创建表
    oracle常见错误
    GUID是什么意思及Guid在sqlserver中的使用
    表中查询重复的数据,如何通过sql语句查询?
  • 原文地址:https://www.cnblogs.com/NJUWZ/p/7101166.html
Copyright © 2011-2022 走看看