我的解答如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <list>
using namespace std;
// 用于存储stack[i]中从下标x到y的和的结构,i = 1,2,3...n
typedef struct {
long x;
long y;
long value;
} Sum;
// 题目所规定的栈数的上限
const int maxNumber = 1000;
// 用于存储每个栈的大小,为了方便从1开始使用,故多申请了一个
long stackSize[maxNumber+1];
// 采用分离链接法的哈希表,存储在递归过程中所计算的stack[i]从下标x到y的和,以缩
// 短计算时间,栈序号直接作为哈希表的存储位置
list<Sum> solveCache[maxNumber+1];
// 递归解决,即要计算stack[n]中从x到y的和,则计算stack[n-1]中从x对应位置nx到y对应
// 位置ny的和,依次类推,同时将每次的计算结果保存在哈希表中以防止重复计算,从而
// 加快计算速度
static long solve(long x, long y, int n);
int main(void)
{
int number;
long x, y;
// 输入栈的数目
scanf("%d", &number);
while (number) {
// 在计算开始前将用于存储栈大小的数组以及哈希表清空
memset(stackSize, 0, sizeof(stackSize));
for (int i = 1; i <= number; i++)
solveCache[i].clear();
// 输入每个栈的大小
for (int i = 1; i <= number; i++)
scanf("%ld", &stackSize[i]);
// 输入所求和的下标
scanf("%ld%ld", &x, &y);
// 调用solve函数递归进行求解
printf("%ld\n", solve(x, y, number));
// 输入下一组数据
scanf("%d", &number);
}
}
static long solve(long x, long y, int n)
{
// 如果所求问题已被计算过,则直接从哈希表中读取计算结果
list<Sum>::iterator cur = solveCache[n].begin();
while (cur != solveCache[n].end()) {
if (cur->x == x && cur->y == y)
return cur->value;
cur++;
}
// 如果未被计算过,则分情况进行计算
// 如果在stack[1]中求和,则直接进行计算即可
if (n == 1) {
Sum sum = {x, y, (x+y)*(y-x+1)/2};
solveCache[n].push_back(sum);
return sum.value;
}
// 如果栈序号大于1,则计算下标x、y在前一个栈中所对应的下标nx、ny
// 根据y - x 是否等于nx - ny来分别进行计算
long nx, ny;
// count the responsing index nx, ny in stack n-1
if (x % stackSize[n-1] == 0)
nx = 1;
else
nx = stackSize[n-1] - x % stackSize[n-1] + 1;
if (y % stackSize[n-1] == 0)
ny = 1;
else
ny = stackSize[n-1] - y % stackSize[n-1] + 1;
if (y - x == nx - ny) {
Sum sum = {x, y, solve(ny, nx, n-1)};
solveCache[n].push_back(sum);
return sum.value;
}
else {
if (y - x + 1 > stackSize[n-1] - (ny - nx) + 1) {
Sum sum;
sum.x = x;
sum.y = y;
sum.value = solve(1, nx, n-1) + solve(ny, stackSize[n-1], n-1)
+ solve(1, stackSize[n-1], n-1) * ((y - x + 1) / stackSize[n-1]);
solveCache[n].push_back(sum);
return sum.value;
}
else {
Sum sum = {x, y, solve(1, nx, n-1) + solve(ny, stackSize[n-1], n-1)};
solveCache[n].push_back(sum);
return sum.value;
}
}
}
怎么感觉你说的题目和我说的不是一个呢, 我说的是浙大acm上面编号2962 StackByStack那道....,在提交程序后,老是出现Float Point Error, 貌似是数据超出表示范围什么的