HDU 5916 Harmonic Value Description

题目来源:2016 CCPC 长春站
题意:
定义一个排列p1,p2,p3....pn的调和数值如下方公式。例如一个数列 1,2,3,4,5 的调和值就为4。
现在给出一个k,求出调和值第k小的一个permutation,这个permutation不唯一
调和数值计算公式

思路:
首先可以先构造出来一个调和值为k的一对数,然后再让其他数前后调和值为1就ok了。
如果两个数gcd() = k , num1 = i * k , num2 = j * k ( i != j && i , j >= 1 ),那最小的两个数就为 k 和 2k 正好与题目中数据范围提示相对应

For each test case, there is only one line describing the given integers n and k (1≤2k≤n≤10000).

  1. 说明现在的思路是正确的,接下来的问题很重要,如何保证后面的排列中相邻两个数的gcd = 1呢?
    只需要让序列为2k,k,k-1,k-2....1,k+1,k+2....2k-1, 2k+1,.....n即可,或者是2k,k,k-1,k-2....1,n,n-1...,2k+1,2k-1,.....,k+1
  2. 那能不能交换一下2k和k的位置?
    不能,如果交换位置后序列为了保持后面排列中相邻两个数gcd = 1就得这样排序k,2k,2k-1,2k-2....k+1,k-1,...1,2k+1,2k+2....n,需要注意的是 k+1 和 k-1的gcd 不一定等于1例如k = 3 gcd(2,4) = 2

     /*************************************************************************
       > File Name: test3.cpp
         > Author:    WArobot 
         > Blog:      http://www.cnblogs.com/WArobot/ 
         > Created Time: 2017年04月17日 星期一 14时03分28秒
      ************************************************************************/
    
     #include<bits/stdc++.h>
     using namespace std;
    
     int n,k;
     void solve(){
         printf(" %d %d",2*k,k);
         for(int i=k-1;i;i--)    printf(" %d",i);
         for(int i=n;i>=k+1;i--){
             if(i!=2*k)  printf(" %d",i);
         }
         printf("\n");
     }
     int main(){
         int t , kase = 0;
         scanf("%d",&t);
         while(t--){
             scanf("%d%d",&n,&k);
             printf("Case #%d:",++kase);
             solve();
         }
         return 0;
     }

刚开始不清楚permutation是不是唯一的,按逻辑来讲自然是不唯一,但是真正去做的时候却不敢去尝试了,总想一次性做对,太过理想化了。

转载于:https://www.cnblogs.com/WArobot/p/6723380.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值