一:题目
二:代码实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string>
unsigned int N, Sp, Sq, A_min, B_min;
//1<= N <=2^20是P,Q两个数组的元素个数,1 <= Sq,Sp <= 2^10分别是两个数组每个元素所占字节大小,所以两个数组分别最大占2^30字节
unsigned long long Qofs, Pofs, K;
//由公式偏移可以知道Pofs原来可能是2^30,先向左偏移会越界,所以选用一个较大的数据类型来存放
//重点:Qofs按照格式可以知道偏移量是同Pofs一样递增,而且按照题目所说,使用偏移公式,Q数组可以不连续,而且不会重叠
//因为Pofs最大30位,所以偏移不会超过30位,因此最大不会超过60位
void main()
{
FILE* fp = freopen("data9.in", "r", stdin);
freopen("data9.out", "w", stdout);
while (!feof(fp))
{
scanf("%d %d %d", &N, &Sp, &Sq);
K = 0xffffffffffffffff,A_min = B_min = 32; //64位
Pofs = (N-1)*Sp; //直接是P数组最大偏移值去获取Q数组最大偏移值,从而获取K最小值
for (int A = 0; A < 32; A++)
{
for (int B = 0; B < 32;B++)
{
Qofs = (Pofs + (Pofs << A) >> B)+Sq; //按照上面文章所说,书上公式是错误的额,这个公式是对的
if (Qofs < K && Qofs >= N*Sq) //找到的第一个最小K,获取的A,B就是最小的,我们不需要设置<=k去判断后面的AB值,没有必要
{
K = Qofs;
A_min = A;
B_min = B;
}
}
}
printf("%llu %u %u
", K, A_min, B_min);
getchar();
}
freopen("CON", "r", stdin);
freopen("CON", "w", stdout);
}