Milking Cows

本文介绍了一种通过链表实现的算法,用于解决N个有序对(an,bn)在数轴上的填充问题,旨在找到最大填充长度及最大空白长度。算法通过插入操作更新链表,并最终遍历链表获取结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题意
:有N个有序对(an, bn),其中最大的max,最小的min,每一个有序对(an, bn)可以在数轴上填满从an到bn这一段长度。求这N个有序对在min到max这段上填充后,最大的填满长度和最大的空白长度。


解题思路

  1. 一次读入每个有序对
  2. 用一个链表来代表这个数轴,链表的每一个Node代表一段被填充的部分
  3. 对每个读入的有序对进行插入操作。在插入的时候要分情况考虑,如果新加入的Node与已存在的Node没有交集,则新建。如果有交集,则只需要修改相应Node的值和指针就行。
  4. 遍历一遍链表,即可得到结果。


代码


/*
ID: zc.rene1
LANG: C
PROG: milk2
*/
#include<stdio.h>
#include<stdlib.h>

struct unit{
	int min;
	int max;
	struct unit * next;
};

FILE *fin;
FILE *fout;

void do_count(struct unit * list_head){
	int during_max=0, empty_max=0, pre_value;

	list_head=list_head->next;
	during_max=list_head->max-list_head->min;
	pre_value=list_head->max;
	while(list_head->next->max<=1000000){
		list_head=list_head->next;
		
		if((list_head->max-list_head->min)>during_max){
			during_max=(list_head->max-list_head->min);
		}
		if((list_head->min-pre_value)>empty_max){
			empty_max=(list_head->min-pre_value);
		}
		pre_value=list_head->max;
	}
	fprintf(fout, "%d %d\n", during_max, empty_max);
}

void do_insert(struct unit * list_head, int time_from, int time_to){
	//keep searching until left foot is on the ground
	struct unit *current=list_head;
	
	while(current->min > time_from || current->next->min <= time_from){
		current=current->next;	
	}
	
	//keep searching until right foot is on the ground
	struct unit *current_p=current;
	while(current_p->min > time_to || current_p->next->min<= time_to){
		current_p=current_p->next;
	}
	
	//if a new node is needed
	if(current==current_p&& time_from>current->max){
		struct unit* new=(struct unit *)malloc(sizeof(struct unit));
		new->min=time_from;
		new->max=time_to;
		new->next=current->next;
		current->next=new;
	}
	else{
		if(time_from > current->max){
			if(time_to > current_p->max){
				current_p->min= time_from;
				current_p->max= time_to;
				current->next=current_p;
			}
			else{
				current_p->min= time_from;
				current->next=current_p;
			}
		}
		else{
			if(time_to > current_p->max){
				current->max= time_to;
				current->next= current_p->next;
			}
			else{
				current->max= current_p->max;
				current->next= current_p->next;
			}
		}
	}
}


int main(void){
	struct unit * list_head=(struct unit *)malloc(sizeof(struct unit));
	fin=fopen("milk2.in", "r");
	fout=fopen("milk2.out", "w");
	int number_of_input;
	int time_from, time_to;

	fscanf(fin, "%d", &number_of_input);
	
	list_head->min=-2;
	list_head->max=-1;
	
	list_head->next=(struct unit *)malloc(sizeof(struct unit));
	list_head->next->min=1000001;
	list_head->next->max=1000002;
	list_head->next->next=NULL;

	for(; number_of_input>0; number_of_input--){
		fscanf(fin, "%d %d", &time_from, &time_to);
		do_insert(list_head, time_from, time_to);
	}
	
	do_count(list_head);

	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值