HDU-计算机学院大学生程序设计竞赛(2015’11)1006 逆袭指数(枚举)

65 篇文章 0 订阅


1001-搬砖(贪心):http://blog.csdn.net/idealism_xxm/article/details/50097051
1002-投币洗衣机(模拟):http://blog.csdn.net/idealism_xxm/article/details/50097231
1003-玩骰子(枚举) :http://blog.csdn.net/idealism_xxm/article/details/50097691
1004-质方数(打表):http://blog.csdn.net/idealism_xxm/article/details/50097255
1005-ACM组队安排(排列组合):http://blog.csdn.net/idealism_xxm/article/details/50097801
1007-油菜花王国(并查集):http://blog.csdn.net/idealism_xxm/article/details/50097473
1008-游乐场(贪心):http://blog.csdn.net/idealism_xxm/article/details/50097577


逆袭指数

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


Problem Description
  这依然是关于高富帅小明曾经的故事——

  尽管身处逆境,但小明一直没有放弃努力,除了搬砖,小明还研究过东方的八卦以及西方的星座,一直试图在命理上找到自己能够逆袭的依据。

  当这些都失败以后,小明转向了数学研究,希望从中得到一些信息。一天,小明在研究《BestCoder逆袭的数理基础》这本书时,发现了宝贵的信息,其中写道:
  每个人都存在一个逆袭指数,对于这个逆袭指数,可能存在连续的因子,如果这个连续因子足够长的话,那么这个人逆袭的概率就很大!

  小明已知自己的逆袭指数,请告诉小明他最长的连续因子,以让他来判断他自己是否能够逆袭。
 

Input
输入包含多组测试数据。
每组数据占一行,包含一个整数N,表示小明的逆袭指数,N小于2^31。
 

Output
对于每组数据,请输出2行:
第一行输出最长的因子个数;
第二行输出最小的因子序列,具体请参考样例。

特别说明:由于小明十分讨厌单身,所以1不算因子。
 

Sample Input
  
  
630 12
 

Sample Output
  
  
3 5*6*7 2 2*3
Hint
630 = 3*5*6*7


n的范围比较大,第一映象就是没法枚举

最后再看时,如果枚举的话,随着ansLen和sta的增加,从sta开始的ansLen+1个数的积很快便会大于n,可以大幅降低枚举的个数

超时后发现,如果n是质数,则会超时,没想到如何有效判断,都已经想用Miller_Rabin先判断是否为素数,再计算

看到别人思路,才想起O(sqrt(n))判断一个数是否为素数的方法,而且能直接融合进枚举过程中


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int n,t,mx,ansSta,ansFin,ansLen,sta,fin;

int cal(int s,int len) {//计算从s开始的len个数的积
    int num=1,i=0;
    for(;i<len;++i)
        num*=s+i;
    return num;
}

int main() {
    while(1==scanf("%d",&n)) {
        mx=n>>1;
        ansSta=ansFin=1;
        ansLen=0;
        for(sta=2;n>=cal(sta,ansLen+1);++sta) {//如果n大于等于从sta开始的ansLen+1个数的积,则继续
            if(n<sta*sta&&ansLen==0) {//如果n是质数
                ansLen=1;
                ansSta=n;
                ansFin=n+1;
                break;
            }
            t=n;
            for(fin=sta;t%fin==0;++fin)//n能被sta..fin-1整除
                t/=fin;
            if(fin-sta>ansLen) {//如果连续的长度大于以前的,则更新
                ansSta=sta;
                ansFin=fin;
                ansLen=fin-sta;
            }
        }
        printf("%d\n%d",ansLen,ansSta++);
        while(ansSta<ansFin)
            printf("*%d",ansSta++);
        printf("\n");
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值