【JZOJ】阿里郎

D e s c r i p t i o n Description Description

将n个人按n的所有约数d分成d种情况,每种情况有n/d个环,第一环的分布为1,d+1,2d+1…n-d+1,第二个环为2,d+2,2d+2…n-d+2,第d个环为d,2d,3d…n
对于一个点而言,它在每一种情况内的相邻点与这个点的编号都不能跟一样
给出n,请求出n个点的编号

I n p u t Input Input

一行,一个整数n。

O u t p u t Output Output

若有解,输出一行n 个字符。第i 个字符表示第i 号演员衣服的颜色,用小写英文字母表示。若有多种方案,请输出字典序最小的方案。
若无解,你得给家属留些话,输出"Impossible" 。

S a m p l e Sample Sample I n p u t Input Input

7

S a m p l e Sample Sample O u t p u t Output Output

abababc

H i n t Hint Hint

2 <= n <= 300000.

T r a i n Train Train o f of of T h o u g h t Thought Thought

找出所有的约数(除了它本身),枚举每一个点,再枚举每一种情况,记录邻点的编号,在26个编号中排除

C o d e Code Code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,tot,s[30005],a[300005],p[35];
int main()
{
	freopen("arilang.in","r",stdin);
	freopen("arilang.out","w",stdout);
	scanf("%d",&n);
	for (int i=1; i<n; ++i)
	 if (n%i==0) s[++tot]=i; //求出约数
	a[1]=1; p[1]=true; 
	for (int i=2; i<=n; ++i)
	{
		for (int j=1; j<=tot; ++j)
		  p[a[(i+s[j]-1)%n+1]]=p[a[(i+n-s[j])%n]]=1;//相邻的两个点
		for (int j=1; j<=26; ++j)
		 if (!p[j]) { 
		  a[i]=j; break;//选编号
		} 
		if (!a[i]) {
			printf("Impossible");
			return 0;
		}//若没有编号可选,自然就是不可行
		memset(p,0,sizeof(p));
	} 
	for (int i=1; i<=n; ++i)
	 printf("%c",a[i]+96);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值