会场安排问题----C语言

假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场.设计一个有效的贪心算法进行安排。
这个问题先要使用贪心算法,那么将所有活动用贪心算法排一遍,然后将剩下活动里剩下的活动继续用贪心算法解决,一直到把所有的活动都安排完。每用一次贪心算法,会场数+1.直到吧活动安排结束。
使用贪心算法的前提是:将活动按照活动结束时间非减序排列。
这样就把整个问题解决了。
下面看看具体实现:

#include<stdio.h>
#include<Windows.h>
#pragma warning(disable:4996)
#define NUM 100
void resort(int *f,int *s,int n){
	int i = 0;
		int j = 0,k=0;
		for (; j < n; j++){
			for (k=j+1; k < n ; k++){
				if (*(f + j)>*(f + k)){
					int temp = *(f + j);
					*(f + j) = *(f + k);
					*(f + k) = temp;
					int temp1 = *(s + j);
					*(s + j) = *(s + k);
					*(s + k) = temp1;
				}
				
			}
		}
		while (i < n){
			printf("第%d个s:%d ", i + 1, *s++);
			printf("第%d个f:%d ", i+1,*f++);
			i++;
			printf("\n");
		}
}
void greedy(int *f,int *s,int *c,int n1){
	int i = 0,n=i,j=0;
	for (i = 0; i < n1; i++){
		if (*(c + i) == 0){
			if (j == 0){//数组c里面第一个为0的元素,对应下标的活动被标记。
				*(c + i) = 1;
			}
			j++;
			}
			if (*(f + n) <= *(s + i + 1)){
				*(c + i + 1) = 1;
				n = i + 1;
			}
			else{
				continue;
				}
	}
	i = 0;
	while (i<n1){
		printf("%d ", c[i]);
		i++;
	}printf("\n");
}
int Getnumber(int *f,int *s,int *c,int n2){
	int i = 0,flag=n2+1;
	int sum=0;
	while (flag){
		int jud = 0;
		for (i = 0; i < n2; i++){
			jud = jud + *(c + i);
		}
		if (jud == n2){
			return sum;
			break;
		}
		else{
	//c[i]的值为1表示,该值下标的f,s数组元素已经被排好。反之还未被排序
			greedy(f,s,c,n2);
			sum++;
		}flag--;
	}
	}
int main(){
	int f[NUM] = { 0 };
	int s[NUM] = {0};
	int ci[NUM] = {0};
	int num = 1;
	printf("请输入活动数目:" );
	scanf("%d", &num);
	for (int i = 0; i < num; i++){
		printf("第%d个活动的开始时间:", i + 1);
		scanf("%d", &s[i]);
		printf("第%d个活动的结束时间:", i + 1);
		scanf("%d", &f[i]);
		printf("\n");
	}
	resort(f, s,num);
	printf("需要%d个场地!\n",Getnumber(f,s,ci,num));
	system("pause");
	return 0;
}

大概讲一下,这里的f数组表示,将活动结束时间存入。s数组里面存的是活动开始时间。
resort函数是对活动结束时间进行非减序排列。即f数组按照增序排列,对应的也将s数组改变顺序。这样就将活动排好序了。
ci数组是用来表示对应下标的活动是否被安排,如果被安排,则将该下标ci元素置1,否则为0,。
这里我使用了getnumber函数调用greedy函数。调用条件是:如果有n个活动,那么ci数组的前n项的和为n的话就会循环结束,得到会场数,否则就一直调用greedy函数。
这样就写完了这个题目。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值