PAT 1044 Shopping in Mars

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;
}


你可能感兴趣的:(PAT 1044 Shopping in Mars)