链接:https://ac.nowcoder.com/acm/contest/847/C
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
Special Judge, 64bit IO Format: %lld
题目描述
在blueland上有 n n个水果店,它们的编号依次为 0,1,2...n−1 0,1,2...n−1。奇妙的是,每个水果店都只卖一种水果,且这些水果店卖的水果种类都各不相同。
在每个水果店有一个传送门,且这些传送门也有各自的编号,其中 i i号水果店的传送门编号为 Ai Ai,每个传送门的编号也各不相同,且是 [0,n−1] [0,n−1]中的一个整数。简单的说, A0A1A2...An−1 A0A1A2...An−1是 0∼n−1 0∼n−1的一个排列。
lililalala初始位于 0 0号水果店,现在他想买到全部的 n n种水果,但是他并不认识路,所以只能通过传送门往来于水果店并通过固定的流程买水果:
当他到达 i i号水果店时,如果之前没有到过这个水果店,那么lililalala会买下这种水果并且通过这个水果店的传送门传送到 (i+Ai)modn (i+Ai)modn号水果店;
如果之前已经到过这个水果店,那么他就立即停止买水果的流程。
请输出一种使得lililalala可以买到全部 n n种水果的一种传送门编号序列,或者判定不存在这样的序列。
输入描述:
仅一行一个整数 n(1≤n≤100000) n(1≤n≤100000)。
输出描述:
如果存在符合题目要求的序列:
输出一行 n n个整数--符合题目要求的序列,如果有多个序列满足要求,输出任意一个即可。
输出需要保证:
∀i∈[0,n−1],Ai∈[0,n−1]∀i∈[0,n−1],Ai∈[0,n−1]
∀i,j∈[0,n−1],满足Ai≠Aj如果i≠j∀i,j∈[0,n−1],满足Ai≠Aj如果i≠j
如果不存在符合题目要求的序列,输出 −1 −1。
示例1
输入
复制
8
输出
复制
6 3 7 2 0 5 1 4
说明
lililalala经过水果店的顺序是:
0→6→7→3→5→2→1→4 0→6→7→3→5→2→1→4
答案可能不止一种。
示例2
输入
复制
10
输出
复制
8 4 9 1 3 0 6 2 5 7
说明
lililalala经过水果店的顺序是:
0→8→3→4→7→9→6→2→1→5 0→8→3→4→7→9→6→2→1→5
答案可能不止一种。
题意:
有n个店铺,编号0~n-1,每个店铺有一个Ai,从这个店铺能到达的店铺编号为(i+Ai)%n,刚开始在0号,让你找一个排列A0~An-1,Ai∈(0,n-1),每个Ai各不相同,也就是0~n-1这个序列全排列的一种,n<=100000
思路:我刚开始一直构造,但是一直构造不出来。若真的构造不出来,就一定不能懒,一定要打表。打表,找规律,构造
打表代码:
#include<bits/stdc++.h>
using namespace std;
#define Max 15
int book[Max],a[Max],res[Max],flag ;
void dfs(int u,int sum,int n)
{
if(book[u]) return ;
book[u] = 1;
if(sum==n)
{ a[u] = 0;
flag = 1;
for(int i = 0;i<n;i++)
{
if(i) printf(" ");
printf("%d",a[i]);
}
printf("\n");
}
for(int i = n-1;i>=0;i--)
{
if(!res[i])
{
res[i] = 1;
a[u] = i;
dfs((u+i)%n,sum+1,n);
res[i] = 0;
}
}
book[u] = 0;
}
int main()
{
for(int i = 1;i<=1;i++)
{
memset(book,0,sizeof(book));
memset(res,0,sizeof(res));
printf("i==%d -->",i);
flag = 0;
dfs(0,1,i);
if(!flag)
printf("NO\n");
}
}
可以见得
n为奇数时,不存在序列
n为偶数时,构造,下面为一种构造方式
n-1,n-3,n-7 ...3,1,0,n-2,n-4,n-6....4,2
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
if(n==1) printf("0\n");
else if(n&1) printf("-1\n");
else
{
for(int i = 1; n-i>0; i += 2)
printf("%d ",n-i);
printf("0");
for(int i = 2;n-i>0;i+=2)
printf(" %d",n-i);
printf("\n");
}
return 0;
}