Buy Fruits(打表,找规律,构造)

博客源自牛客网题目,描述了blueland上水果店传送门问题,给出输入输出要求及示例。分析得出n为奇数时不存在符合要求的传送门编号序列,n为偶数时可按特定方式构造,如n - 1,n - 3,n - 7...3,1,0,n - 2,n - 4,n - 6....4,2 。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接: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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值