我说,别白嫖
目录
!tips:c语言次幂函数用 double pow(double a, double b) 可求
11075 强盗分赃
题目:
有天夜里5个强盗A、B、C、D、E抢到一大堆金币(金币个数不超过n个,n<=100000000),可是怎么也无法平均分成5份, 吵吵嚷嚷…… 吵累了,只好先睡觉,准备第二天再分。 夜深了,一个强盗A偷偷爬起来,先拿了一个金币私下放自己口袋藏好,再将金币分为5等份,将自己的那一份再私藏好 就去睡觉了。 随着第二个强盗B也爬起来,也是私拿了一个金币再分5等份,也私藏起自己那份就睡觉去了。 后来的三个强盗C、D、E也都是这样办的。 问最初有多少个金币?(最初的金币个数有多种可能,请输出不超过n的所有可能,从小到大排列) 输入格式输入一个数,n, n<=100000000。 请输出金币数不超过n的可能的初始金币个数。 输出格式初始金币个数的多种可能(初始金币个数小于等于n)。 请输出不超过n的“所有的”可能,从小到大排列出,中间空格相连。 如果不超过n没有一种可能,输出impossible(无标点,无大写) 例如输入10,则输出impossible 输入样例8000 输出样例3121 6246 提示此题所说的是:每个强盗私拿1个金币后都可以五等分,再私藏起1份,留下4份。 这样的初始金币个数是怎样的数,才能满足这个条件。 方法一: 此题若仅采用程序实现的话是较为简单的,可使用5次的递归算法或循环处理。 递归算法如下(循环处理也很简单): int count = 0; int func(int num) //判断初始为num的数是否合适?合适返回1,不合适返回0 { int temp = num-1; if(temp%5 == 0 && count<5) { count++; return func(temp/5*4); } else if (count==5) return 1; else return 0; } 但若要分析初始金币个数的通项函数表达就更难一些了。 方法二: 从最后一个强盗往前考虑,假设到第五个强盗E时,平均每个强盗得到x个金币 第五个强盗E藏掉一个金币后剩 5x 个 第四个强盗D藏掉一个金币后剩 5(5x+1)/4 = 25x/4+5/4 = (x+1)/4 + ... 第三个强盗C藏掉一个金币后剩 5(25x/4+5/4+1)/4 = 125x/16+45/16 = 13(x+1)/16 + ... 第二个强盗B藏掉一个金币后剩 5(125x/16+45/16+1)/4 = 625x/64+305/64 = 49(x+1)/64 + ... 第一个强盗A藏掉一个金币后剩 5(625x/64+305/64+1)/4 = 3125x/256+1845/256 = 53(x+1)/256 + ... 因原来共有金币 3125x/256+1845/256+1 = 3125x/256+2101/256 = (12x+8)+53(x+1)/256 这里是突破口: x,(x+1)/4,13(x+1)/16,49(x+1)/64,53(x+1)/256 都应是整数,最后一个条 件 53(x+1)/256 是整数决定了初始金币的最小个数。所以 x=255 时最小的初始 金币总数(12x+8)+53(x+1)/256=3121个。 方法三: 或者这样分析,设金币总数n,由于5个强盗都是先藏一个后,发现余下的金币刚好均分5份, 所以设想在总数中加入4个新金币,则每个强盗占有的金币数不会改变(包括藏了的那一个), 从而每次分金币时这4个假想的金币会留存到后一层总数中,这使得每次分5份都是恰好的整数, 由此可见,n+4至少是5^5的整数倍,所以n的最小值为 5^5-4=3121。 其余可能的n值为 n = k*(5^5)-4,k为大于1的整数。 |
代码:
数学分析法
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
if(n<3121) printf("impossible");
int sum =0;
for(int x=255;; x++){
sum = (12*x + 8)+ 53*(x+1)/256;
if(sum > n) break;
if((53*(x+1)%256)==0)
printf("%d ",sum);
}
return 0;
}
17963 完美数
题目:
现在请你以下列格式输出前8个完美数,每行一个完美数,前面是序号后面是完美数,中间用空格间隔。如: 1 6 2 xx 3 xxx …… 输入格式无 输出格式输出前8个完美数,每行一个完美数,前面是序号后面是完美数,中间用空格间隔。 输入样例无 输出样例1 6 2 xx 3 xxx …… 8 xxxxxxxx 提示欧拉证明了,当2^p-1是素数时,2^(p-1)*(2^p-1)是完美数,而且偶完美数都具有这种 形式。目前还没有发现奇完美数。 一般认为存在有无穷多个完美数,但目前知道的2^p-1是素数的p只有47个,他们依次的 p值如下: 2 3 5 7 13 17 19 31 61 89 107 127 521 607 1279 2203 2281 3217 4253 4423 9689 9941 11213 19937 21701 23209 44497 86243 110503132049 216091 756839 859433 1257787 1398269 2976221 3021377 6972593 13466917 20996011 24036583 25964951 30402457 32582657 37156667 42643801 43112609 这题要求输出前8个,用这个序列的前八个当做p,计算2^(p-1)*(2^p-1)即是完美数。 如果此题采用完美数定义(如果一个数的真约数之和等于这个自然数本身,则这个自然数 就称为完美数)来求解的话,产生不了前八个,会计算超时。 还有,此题需要采用64位的整数才可。 |
代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
int main()
{
int perf[8] = {2,3,5,7,13,17,19,31};
for(int i=0 ;i<8; i++)
{
long long int sum = pow(2,perf[i]-1)*(pow(2,perf[i])-1);
printf("%d %lld\n",i+1,sum);
}
}
按照提示写即可。用数组存储预先数。