题目描述:
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;
}