• 问题 I: 【组合数学】取数问题


    题目描述
    任给出正整数n和k(1<=n<=1,000,000 , 0<=k<=n),取数规则如下:
    例如n=16,k=4
    第一次取数 1 取数后的余数为16-1=15
    第二次取数 2 取数后的余数为15-2=13
    第三次取数 4 取数后的余数为13-4=9
    第四次取数 8 取数后的余数为 9-8=1
    当第五次取数时,因为余数是1,不够取,此时作如下处理
    余数1+k=5,再从1开始取
    第五次取数 1 取数后的余数为5-1=4
    第六次取数 2 取数后的余数为4-2=2
    由于第七次取数4,但余数为2,又得重新加k,2+4=6,再从1开始取
    第七次取数 1 取数后的余数为 6-1=5
    第八次取数 2 取数后的余数为 5-2=3
    第九次取数 4 但不够取
    3+4=7
    第九次取数 1 取数后的余数为 7-1=6
    第十次取数 2 取数后的余数为 6-2=4
    第十一次取数 4 取数后的余数为 4-4=0 正好取完
    由此可见,当n=16,k=4时,按上面方法11次取完
    
    输入
    两个int类型的正整数,n和k。
    
    输出
    如果正好取完,输出按照取数规则取完所需要的取数次数。如果永远不能取完时,输出”Bad Number!”。
    
    样例输入
    复制样例数据
    16 4
    样例输出
    11
    

    设余数为 res
    按照规则, 每次剪掉的数是2 ^ 0 , 2 ^ 1 , 2 ^ 2 , 2 ^ 3 … 2 ^ i , 这个2 ^( i + 1 )> res ,故而不能再减了, 前 i 项我们可以直接用等比做一下 , 我是提前存起来的,然后后面直接相减 , 但是这样的话, 会有一个问题, 我们要循环多少次,才能最后按照规则得出0 呢, 这个还真不知道,
    不过可以发现我们先找出一个规律, 根据等比数列公式, 前i + 1项和 为2 ^(i + 1) - 1 . 比2 ^ (i + 1) 少了 1 , res <= 2 ^ (i + 1) - 1. 我们可以发现res 不超过一半大小, 也就是如果res >= 2 ^ (i + 1) , 我们可以直接减掉2 ^ (i + 1) , 也就保证了res < 2 ^ (i + 1) , =额, 还真有点说不清
    看样例14 6 第一次拿 1 , 2 ,4 ,剩下 7, 下面不够拿8的了, 然后再加上k重新拿, 一次模拟下去可以发现 ,每次剩下的余数真的不超过n的一半大小,那么再加上k,就是不超过k + n / 2, 最后为0 . 会去拿多少次? 每次相当于取走一半, 不回超过k + n / 2 次, 枚举这些遍就行了,如果最后是0 , 可以拿完, 同时记录一下拿了多少次, 如果不是,就是Bad

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int b[31] , n , k ;
    int main()
    {
    	for(int i = 1 , j = 1 ;i <= 30 ;j *= 2 , i ++)
    	 b[i] = b[i - 1] + j ;
    	scanf("%d%d" , &n , &k) ;
    	int total = 0 , res = n ;
    	for(int sum = 0 ;sum <= k + n / 2 ;sum ++ , res += k)
    	{
    	 for(int i = 1 ;i <= 30 ;i ++)
    	  if(b[i] > res) 
    	   {
    	   	res -= b[i - 1] ;
    	   	total += i - 1;
    	   	break ;
    	   }
    	   if(!res) break ;
    	}
    	 if(res) puts("Bad Number!") ;
    	 else printf("%d
    " , total) ;
    	
    	return 0 ;
    } 
    
    每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
  • 相关阅读:
    通用指令-数据库通用操作
    通用指令-key通用操作
    数据类型-sorted_set类型基本操作和扩展操作
    数据类型-set类型基本操作和扩展操作
    数据类型-list类型基本操作和扩展操作
    数据类型-hash类型基本操作和扩展操作
    ORACLE 函数 NVL, NVL2, NULLIF
    maven 配置jdk版本
    maven仓库添加自己的jar包
    Map 中的EntrySet()
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/12870884.html
Copyright © 2020-2023  润新知