• Buy Fruits-(构造)


    https://ac.nowcoder.com/acm/contest/847/C

    在blueland上有 n n个水果店,它们的编号依次为 0,1,2...n1 0,1,2...n−1。奇妙的是,每个水果店都只卖一种水果,且这些水果店卖的水果种类都各不相同。
    在每个水果店有一个传送门,且这些传送门也有各自的编号,其中 i i号水果店的传送门编号为 Ai Ai,每个传送门的编号也各不相同,且是 [0,n1] [0,n−1]中的一个整数。简单的说, A0A1A2...An1 A0A1A2...An−1 0n1 0∼n−1的一个排列
    lililalala初始位于 0 0号水果店,现在他想买到全部的 n n种水果,但是他并不认识路,所以只能通过传送门往来于水果店并通过固定的流程买水果:
    当他到达 i i号水果店时,如果之前没有到过这个水果店,那么lililalala会买下这种水果并且通过这个水果店的传送门传送到 (i+Ai)modn (i+Ai)modn号水果店;
    如果之前已经到过这个水果店,那么他就立即停止买水果的流程。
    请输出一种使得lililalala可以买到全部 n n种水果的一种传送门编号序列,或者判定不存在这样的序列。

    输入描述:

    仅一行一个整数 n(1n100000) n(1≤n≤100000)。

    输出描述:

    如果存在符合题目要求的序列:
    输出一行 n n个整数--符合题目要求的序列,如果有多个序列满足要求,输出任意一个即可。
    输出需要保证:
    i[0,n1],Ai[0,n1]∀i∈[0,n−1],Ai∈[0,n−1]
    i,j[0,n1],AiAjij∀i,j∈[0,n−1],满足Ai≠Aj如果i≠j
    如果不存在符合题目要求的序列,输出 1 −1。
    示例1

    输入

    8

    输出

    6 3 7 2 0 5 1 4

    说明

    lililalala经过水果店的顺序是:
     06735214 0→6→7→3→5→2→1→4
    答案可能不止一种。
    示例2

    输入

    10

    输出

    8 4 9 1 3 0 6 2 5 7

    说明

    lililalala经过水果店的顺序是:
     0834796215 0→8→3→4→7→9→6→2→1→5
    答案可能不止一种。
    解题:
    起点是0,传送到(n-1)号店,再传送到1号店,再传送到n-2号店,再传送到2号店,以此类推,直到n/2传送回0。
    数组jump存储传送到的店号,数组存储传送门的编号,i表示当前水果店
    (i+door[i])%n=jump[i]
    逆推door[i]:
    (i+door[i])/n=x;
    door[i]=x*n+jump[i]-i;
    手撸n为偶数的情况,前后跳。
    比如:n=8
    下标i: 0 1 2 3 4 5 6 7
    jump[i]:7 6 5 4 0 3 2 1
    door[i]:7 5 3 1 0 6 4 2
    显然n/2前面的x都为0,n/2后面的x都为1,n/2特判。
    手撸n为奇数的情况,举例n=3,5,撸不出来。直接输出-1。
    提交一发wa后想到特判n=1的情况。
    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    
    
    int n;
    int jump[100005];///传送到的店号
    int door[100005];///传送门的编号
    
    int main()
    {
        while(cin>>n)
        {
            if(n==1)
                printf("0
    ");
            else if(n%2)
                printf("-1
    ");
            else
            {
                int len=n/2;
                for(int i=0;i<n;i++)
                {
                    if(i<len)
                    {
                        jump[i]=n-1-i;
                    }
                    else if(i==len)
                        jump[i]=0;
                    else
                        jump[i]=n-i;
                }
                for(int i=0;i<n;i++)
                {
                    if(i<len)
                    {
                        door[i]=jump[i]-i;
                    }
                    else if(i==len)
                        door[i]=0;
                    else
                        door[i]=n+jump[i]-i;
    
                }
                /*打印观察规律
                for(int i=0;i<n;i++)
                if(i!=n-1)
                    printf("%d ",i);
                else
                    printf("%d
    ",i);
                for(int i=0;i<n;i++)
                if(i!=n-1)
                    printf("%d ",jump[i]);
                else
                    printf("%d
    ",jump[i]);
                */
                for(int i=0;i<n;i++)
                if(i!=n-1)
                    printf("%d ",door[i]);
                else
                    printf("%d
    ",door[i]);
            }
        }
        return 0;
    }
    
    
    
     
  • 相关阅读:
    C#获取当前路径
    惠普辞退4000员工,今后如何走
    提升你的编码技能,你不知道的免费在线编码资源(上)
    iPhone 5在美销量有望破5000万,Facebook手机何去何从?
    Python获取命令行参数
    C#递归获取文件目录
    Pixel’d:共创美好的像素艺术
    PayPal走向现实支付,消费者们会来买帐吗?
    兼容性测试、手工测试、自动化测试及探索性测试
    冒烟测试 smoking test
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10807016.html
Copyright © 2020-2023  润新知