限制不互素對的排列
阿新 • 來源:網路 • 發佈:2021-02-15
連結:https://ac.nowcoder.com/acm/contest/9981/I
來源:牛客網
題目描述
輸入一個數n,請構造一個長度為n的排列,使得其中正好有k對相鄰的數gcd(最大公約數)大於1。
排列是指1到n一共n個數,每個數都出現過且僅出現過1次。
輸入描述:
兩個整數n和k,用空格隔開。

輸出描述:
如果不存在可行的構造方案,輸出-1。
否則輸出一行n個數,用空格隔開。如果有多組可行的構造方案,輸出任意一組即可。
示例1
輸入
2 1
輸出
-1
說明
長度為2的排列有2個:{1,2}和{2,1},顯然都不符合題意
示例2
複製
6 3
輸出
5 3 6 2 4 1
說明
共有3對相鄰數不互素:{3,6}、{6,2}和{2,4}。
這並不是唯一解,只要構造任意合法解即可。
思路:

注意k的範圍正好是n/2,而且在1-n正好有n/2個偶數,所有的偶數公約數都包含2大於1,也就是說n以內偶數可以組成n-1組我們要求的組數。
然後按照這個思路,我們可以做一個分類,小於4,4-5,大於等於6。小於4的時候是沒有gcd大於1的,4-5是有一組gcd大於1。可以舉例輸出。
然後大於等於6,k大於等於3時,我們可以控制輸出的偶數的數目來控制滿足的組數。假如n=8;k=4;{3 6 2 4}這裡面有三組,但是k是4,所以我們再輸出一個8, {3 6 2 4 8}就滿足k的條件了,而且我們也可以發現,相差為2的奇數,gcd一定為1,相差為1的數,gcd也一定為一,所以後面的數我們直接按照順序輸出就可以了。
注意:
1.當k=n/2的時候需要特判一下不然就會輸出n+1個數
if(p!=n/2) printf(" %d", n);
2.當k等於0的時候任何n都滿足,可以在最前面判斷一下,特別是在小於4的範圍特別容易漏掉。
程式碼:
#include<stdio.h>
int main()
{
int n, k;
scanf("%d%d", &n, &k);
if(n<4)
{
if(k==0)
{
for(int i=1; i<n;i++)
printf("%d ", i);
printf("%d", n);
}
else
printf("-1");
}
else if(n<=5)
{
if(k==0)
{
for(int i=1; i<n;i++)
printf("%d ", i);
printf("%d", n);
}
else if(k==1)
{
printf("1 3 2 4");
if(n==5) printf(" %d", n);
}
else if(k==2)
printf("-1");
}
else
{
if(k==0)
{
for(int i=1; i<n;i++)
printf("%d ", i);
printf("%d", n);
}
else if(k==1)
{
printf("1 3 2 4");
for(int i=5; i<=n;i++)
printf(" %d", i);
}
else if(k==2)
{
printf("2 3 6 4 1 5");
for(int j=7; j<=n; j++)
printf(" %d", j);
}
else
{
int i, p;
printf("3 6 2 4");
p=k;
k-=3;
for(i=8; k>0; k--,i+=2)
{
printf(" %d", i);
}
printf(" 1");
for(int j=5; j<i&&j<=n; j+=2)
printf(" %d", j);
for(int j=i; j<n; j++)
printf(" %d", j);
if(p!=n/2)
printf(" %d", n);
}
}
return 0;
}
