二分法选课

题目描述:

David一个叫做“二分查找“的算法。该算法用于对有序数列中元素的快速查找。基本思想是通过将元素和数列中间元素比较大小,通过比较结果将查找范围缩小到数列左一半或右一半,不断重复、对半缩小查找范围,从而在更短的时间内完成查找。

举个例子:对于一个升序的数列a,a[l],a[r]分别为数列左端和右端,查找x。

1.     令m=(l+r)/2

2.     若r≥l,比较x和a[m];否则查找失败,结束

3.     若x>a[m],令l=m+1,回到1

4.     若x<a[m],令r=m-1,回到1

5.     若x=a[m],则找到了,结束

代码示例如下:

l=1,r=n,m=(l+r)/2;

sol=0;

while (l<=r){

       if (x<a[m])

              r=m-1;

       else if (x>a[m])

              l=m+1;

       else{

              sol=m;

              break;

       }

       m=(l+r)/2;

}

if (sol)

       printf("x=a[%d]\n",&sol);

else

       printf("Failed\n");

 

近期,David的叔叔恰好在经营一个乡村振兴网络课程平台。而David的任务就是编写一个选课系统。平台会告诉你所有的课程编号及其名额;客户会告诉你他想选的课程编号和人数。若客户提交的编号不存在,请回复“ERR”;若编号存在,但剩余人数不足,请回复“Failed”;若编号存在,且剩余人数足够,则选课成功,回复“Succeeded”。

输入格式:

第1行输入两个整数n,t,代表课程数目和客户访问次数

接下来n行,每行两个整数id,x,分别代表课程编号和剩余名额。

接下来t行,每行两个整数id,x,分别代表客户选择的课程编号和人数

输出格式:

共t行,每一行为对客户的回复,格式见题目描述。

样例输入:

4 5

130 30

520 120

329 60

211 15

211 10

520 120

714 0

130 40

211 10

样例输出:

Succeeded

Succeeded

ERR

Failed

Failed

数据范围:

1≤n≤300,1≤t≤10000,1≤id≤2^32-1,1≤x≤300

# include<stdio.h>
# include<stdlib.h>
/*David一个叫做“二分查找“的算法。该算法用于对有序数列中元素的快速查找。
基本思想是通过将元素和数列中间元素比较大小,通过比较结果将查找范围缩小
到数列左一半或右一半,不断重复、对半缩小查找范围,从而在更短的时间内完成查找。
举个例子:对于一个升序的数列a,a[l],a[r]分别为数列左端和右端,查找x。
1.令m=(l+r)/2
2.若r≥l,比较x和a[m];否则查找失败,结束
3.若x>a[m],令l=m+1,回到1
4.若x<a[m],令r=m-1,回到1
5.若x=a[m],则找到了,结束
代码示例如下:
l=1,r=n,m=(l+r)/2;
sol=0;
while (l<=r){
       if (x<a[m])
              r=m-1;
       else if (x>a[m])
              l=m+1;
       else{
              sol=m;
              break;
       }
       m=(l+r)/2;
}
if (sol)
       printf("x=a[%d]\n",&sol);
else
       printf("Failed\n");
近期,David的叔叔恰好在经营一个乡村振兴网络课程平台。
而David的任务就是编写一个选课系统。平台会告诉你所有的课程编号
及其名额;客户会告诉你他想选的课程编号和人数。若客户提交的编号不
存在,请回复“ERR”;若编号存在,但剩余人数不足,请回复“Failed”;
若编号存在,且剩余人数足够,则选课成功,回复“Succeeded”。
输入格式:
第1行输入两个整数n,t,代表课程数目和客户访问次数
接下来n行,每行两个整数id,x,分别代表课程编号和剩余名额。
接下来t行,每行两个整数id,x,分别代表客户选择的课程编号和人数
输出格式:
共t行,每一行为对客户的回复,格式见题目描述。
样例输入:
4 5
130 30
520 120
329 60
211 15
211 10
520 120
714 0
130 40
211 10
样例输出:
Succeeded
Succeeded
ERR
Failed
Failed
数据范围:
1≤n≤300,1≤t≤10000,1≤id≤2^32-1,1≤x≤300
*/
int n, t;
struct course//存课程编号和剩余人数 
{
	int id, x;//int占32位(4字节 
}c[301];

int comp(const void *a, const void *b)//
{
	return(((const struct course *)a) ->id) - 
		  (((const struct course *)b) -> id);
}
int main()
{
	scanf("%d%d", &n, &t);//存课程数与访问数 
	for(int i = 1; i <= n; ++i/*无返回值时与i++等效*/)//由于i从1开始,用<= ,++i, 
		scanf("%d%d", &c[i].id, &c[i].x);//课程容量与id 
		
	qsort(c + 1, n , sizeof(c[0]), comp);//快排函数,在stdlib.h 
	
	for(int i = 1, id, x; i <= t; ++i)//输入用户访问 
	{
		scanf("%d%d", &id, &x);//用户所需容量与id 
		int l = 1,r = n, mid = (l + r)/ 2/*二分*/, sol = 0;
		while(l <= r)
		{
			if(id < c[mid].id )//比较,先找到对应id 
				r = mid - 1;//偏小,调二分区间上限
			else if(id > c[mid].id)//偏大 ,调二分区间下限 
				l = mid +1;
			else//恰好为中间,直接退循环 
			{
				sol = mid;
				break;
			}
			mid = (l + r)/ 2;
		}
		if(sol)//初始时sol为0,sol不为0表示有对应id 
		{
			if(x > c[sol].x)
				puts("Failed");//puts函数自动换行 
			else
			{
				c[sol].x -= x;
				puts("Succeeded");
			}		
		}
		else
			puts("ERR");
	}
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值