ref:
http://tech-wonderland.net/blog/pat-1044-shopping-in-mars.html
想不到思路,实现起来倒是简单,关键是采用struct记录比较方便:
typedef struct{
int idx;//j, and i...j之和是M或刚超过M的临界值
int sum;
}record;
#include <stdio.h>
typedef struct{
int idx;//j, and i...j之和是M或刚超过M的临界值
int sum;
}record;
int n, m;
int d[100000+5];
record rs[100000+5];
int main(){
freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i = 0; i < n; i++){
scanf("%d",&d[i]);
}
int sum = 0;
int j;//记录结尾的下标
for(int i = 0; i < n; i++){
sum = (i == 0) ? 0 : rs[i-1].sum-d[i-1];//前一个i的sum减去d[i]
j = (i == 0) ? -1 : rs[i-1].idx;
while(sum < m && j<n){
j++;
sum += d[j];
}
record tmp;
if(j < n){
tmp.idx = j;
tmp.sum = sum;
rs[i] = tmp;
}else{
tmp.idx = -1;//从i开始往后的所有元素之和都小于m, 不必要再遍历了
tmp.sum = -1;//否则sum仍然是上一个i的sum
rs[i] = tmp;
break;
}
}
//test
/*for(int i = 0; i < n; i++){
if(rs[i].idx == -1){
break;
}else{
printf(" %d - %d, sum = %d\n",i,rs[i].idx, rs[i].sum);
}
}*/
int closest = rs[0].sum;//因为题目说总量是足够支付的,即sum最小也有M
for(int i = 0; i < n; i++ ){
if(rs[i].idx == -1){
break;
}else if(rs[i].sum < closest){//rs[i].sum不会小于m
closest = rs[i].sum;
}
}
for(int i = 0; i < n; i++){
if(rs[i].sum == closest){
printf("%d-%d\n",i+1, rs[i].idx+1);
}
}
return 0;
}