原题连接:https://vjudge.net/problem/UVA-1591
分类:函数
备注:阅读理解
前言:紫书说这题比较抽象,这是真的抽象啊,我估计就算我的母语是英语也不一定能读懂到底什么意思。还是看了别人的解释,推一篇https://blog.csdn.net/XieNaoban/article/details/52199420。
题目意思
大概是这样的,有P,Q两个数组,P数组每个元素的长度为Sp,Q数组每个元素长度为Sq,两数组都有一共n个元素。Pofs(i)表示P数组第i个元素偏移量,Qofs(i)同理。
认为P数组第一个元素偏移量为0,第二个元素偏移量为Sp,第三个为2*Sp,以此类推,偏移量加数组的首地址则是指数组元素的首地址。
题目给了公式Qofs’(i)=(Pofs(i)+(Pofs(i)<<A))>>B,注意Qofs’(i)有一撇,它不等价于Qofs(i),它们的关系应该是Qofs’(i)>=Qofs(i),也就是说用公式计算出的偏移量大于等于低效率(乘除法)算出来的偏移量,用这个公式计算的偏移量来查询数组就可能会使得数组浪费一点空间,但是这个公式它算的快,所以认为这样是值得的。
我认为可以这样理解:用公式得到的Qofs’(i)>=Qofs(i),初始地址加上这个偏移量则得到第i个元素的首地址,用该公式计算的偏移量访问元素可能导致两个元素之间的空置空间大于等于老老实实算出来的偏移量来访问元素,即Qofs’(i+1)-Qofs’(i)>=Qofs(i+1)-Qofs(i)
如果老老实实算偏移量Qofs(i),则从Q数组的首地址到Q数组最后一个元素的末地址的长度应该为N*Sq,即Q数组占有的空间大小的最小值,那么用公式算出的得到空间大小为K,K>=N*Sq,K=Qofs’(n)+Sq(看了大佬的代码才知道K是这么算啊),这样解释一下吧:已知Qofs(i+1)-Qofs(i)=Sq,那么类似地设Qofs’(i+1)-Qofs(i)=Sq’,则Qofs’(n)=(n-1)*Sq’,再强调一下第一个元素偏移量为0,那么指向第n个元素偏移量要为两元素间距乘以(n-1),那么当我们得到了第n个元素的首地址,因为已经知道,低效率访问元素的Q数组的一个元素长度为Sq,那么K只要为Qofs’(n)加上Sq即可,而不是去加绝不可能更小的Sq’(我们访问元素需要的只是首地址,空间能省还是得省的)。
这里的Sq’是题目是我自己假设的,题目中没有,要算Qofs’(i)套题目公式就可以了,遍历A,B就能把题目做出来。
代码如下:
#include<stdio.h>
typedef long long ll;
const ll inf = 1LL << 31;//数据最大不超过2^30即 N(2^20)*Sq(2^10)
int N, Sp, Sq;
void find()
{
ll maxPofs = 1LL * (N - 1) * Sp;//最大偏移量时指向最后一个元素,偏移量为0时指向第一个元素
ll minQofs = 1LL * N * Sq;//需要的最小内存
ll K = inf, A = 0, B = 0;
for (int i = 0; i < 32; i++)
for (int j = 0; j < 32; j++)
{
ll temp = ((maxPofs + (maxPofs << i)) >> j) + Sq;
if (temp >= minQofs && K >= temp)
if (K > temp) K = temp, A = i, B = j;
else if (i < A)A = i, B = j;
}
printf("%lld %lld %lld\n", K, A, B);
}
int main(void)
{
while (scanf("%d%d%d", &N, &Sp, &Sq) == 3)find();
return 0;
}
虽然我知道就算看的很懂也会理解不了题意,但是我这英语水平连翻译都是个问题啊喂!潜心修炼英语吧,不然题目都不配做。