BUPT计导作业12.17~12.18指针、结构体代码参考

坐标:BUPT;OJ:Excited OJ (BOJ-V4)

第十二次练习

这五道题甚至连名字都没有,我只能把题面也放了上来,或许是因为他们太水了 ,是因为他们都是很经典的练习题,我也没有用投机取巧的办法,就按题目描述来做,就当练练手熟。
在开头先声明一下与题目本身无关的注意点,各式各样常犯的基(sha)础(diao)错误:

  • 在scanf函数中传入地址,忘加&取址符
  • 在读入n前,就以n为长度开变长数组
  • 在输入输出时,%f%lf%lld弄混
  • 多语句时,未用{}将他们括起来(导致if,for作用域改变)

希望你能阅读愉快,并有所收获,看到很多身边的人与我一起分享知识本身就是一件很愉快的事情(• ω •)丿❤

A.

已知正整数n,n的范围是1—100。你要从键盘读入n个字符串,每个字符串的长度不确定,但是n个字符串的总长度不超过100000。你要利用字符指针数组将这n个字符串按照ASCII码顺序进行升序排序,然后再打印到屏幕上。字符串中可能包含ASCII码中的任意字符,每个字符串以换行符结束输入。
要求:不允许定义如char str[100][100000];这样的二维数组,因为会极大的浪费内存空间。你应定义char str[100000];这样的存储空间,将n个字符串连续的存储在一维字符空间内,然后将这n个字符串的起始位置保存在字符指针数组中,再进行排序操作。
输入与输出要求:输入一个正整数n,代表待排序字符串的个数,n不超过100,然后是n个字符串,每个字符串的长度不确定,但至少包含1个字符。n个字符串的总长度不会超过100000。输出排序后的n个字符串,每个字符串占一行。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

char *a[100];
char s[100000];

bool cmp(char*, char*);
int max(int, int);

int main()
{
	int n;
	scanf("%d",&n);
	getchar();
	gets(s);
	a[1]=&s[0];
	For(i,2,n)
	{
		int len=strlen(a[i-1]);
		a[i]=a[i-1]+len+1;
		gets(a[i]);
	}
	bool flag;
	for (int i=n-1; i>=1; i--)
	{
		flag=true;
		For(j,1,i)
			if (cmp(a[j],a[j+1]))
			{
				char* t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
				flag=false;
			}
		if (flag==true)
			break;
	}
	For(i,1,n)
		puts(a[i]);
	return 0;
}

int max(int a, int b)
{
	return a>b?a:b;
}

bool cmp(char *a, char *b)
{
	int len=max(strlen(a), strlen(b));
	For(i,0,len)
	{
		if (a[i]>b[i])
			return true;
		else if (a[i]<b[i])
			return false;
	}
}
/*
4
Where there is hope ,there is a way.
Welcome Beijing.
Nice idea.
Have fun.
*/

PS:这一题需要注意:

  • 使用兼容性更好的冒泡排序
  • 注意交换的是指针而非字符串的内容
  • 在scanf读入整数以后getchar来吸收最后的\n(否则第一个串将为空行)

B.

已知正整数n,n的范围不确定。从键盘读入n个字符串,每个字符串的长度小于1000,要保存到动态数组中。为了能访问到所有的字符串,需要建立一个长度为n的动态指针数组,用于保存n个字符数组的内存地址。在读入每个字符串时,用一个长度为1000的字符数组作为缓冲数组,将字符串读入并求出长度后,再动态分配空间,将缓冲数组中的字符串复制到新分配的动态空间中,并将动态空间的首地址保存到指针数组中。读完n个字符串后你要将这n个字符串按照ASCII码顺序升序排序,然后再打印到屏幕上。字符串中可能包含大小写字母“A-Z”、“a—z”与空格字符。每个字符串以换行符结束输入。
输入与输出要求:输入一个正整数n,代表待排序字符串的个数。然后输入n个字符串,每个字符串至少包含一个字符,占一行。输出排序后的n个字符串,每个字符串占一行。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

bool cmp(char*, char*);
int max(int, int);

int main()
{
	int n;
	scanf("%d",&n);
	char *a[n];
	getchar();
	char s[1000];
	char *b[n];
	For(i,1,n)
	{
		gets(s);
		int len=strlen(s);
		b[i]=(char*)malloc(sizeof(char)*(len+1));
		For(j,0,len)
			b[i][j]=s[j];
		a[i]=b[i];
	}
	bool flag;
	for (int i=n-1; i>=1; i--)
	{
		flag=true;
		For(j,1,i)
			if (cmp(a[j],a[j+1]))
			{
				char* t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
				flag=false;
			}
		if (flag==true)
			break;
	}
	For(i,1,n)
		puts(a[i]);
	For(i,1,n)
		free(b[i]);
	return 0;
}

int max(int a, int b)
{
	return a>b?a:b;
}

bool cmp(char *a, char *b)
{
	int len=max(strlen(a), strlen(b));
	For(i,0,len)
	{
		if (a[i]>b[i])
			return true;
		else if (a[i]<b[i])
			return false;
	}
}
/*
10
Bb b
zzz zzz
aab bbccc
aaabbaaa
abb bbb
ccidfjD
Aidj idj
Ccidf jD
sidfjijE EE
kkkkkk
*/

PS:A题和B题是一个问题的两种不同解法,如果能满足一个问题的限制条件(不爆内存),那么任何解法都是有可能的
又:这两个题的字符串比较均可用strcmp函数实现,需要添加头文件string.h

C.

学生的属性包括姓名、学号、5门课程的成绩、平均成绩与总成绩。已知一个学生的姓名、学号与5门课程的成绩,你的任务是计算该学生的平均成绩与总成绩,并将该学生的5门课程成绩按照从高到底进行排序,最后将这个同学的完整信息输出。学生的姓名中只能包含大小写字母与空格字符,不会超过20个字符;学生的学号是个长度不会超过20的字符串,只包含数字字符;课程成绩均为0—100的整数。
要求:
1.在本题中,你要设计一个结构来存储学生的信息。在此结构中,需要有一个字符数组来存储姓名;一个字符数组来存储学号;一个长度为5的整型数组来存储5门课程的成绩;一个双精度浮点型变量存储平均成绩,一个整型变量存储总成绩。
2.在对结构变量的成员进行赋值与排序的时候,你要使用“结构变量名+‘.’+结构成员名”这种方式访问变量,如“student.score”;而在输出学生信息时,你要用一个结构指针指向该结构,然后用结构指针访问结构中的变量,即“结构指针名+‘->’+结构成员名”,如“ptr->score”。
输入与输出要求:学生信息的输入按照姓名、学号、5门课程成绩的顺序输入,共占三行。学生信息的输出:姓名占一行;学号占一行;5门成绩中间用空格分开,最后一个成绩后是换行符,从高到底进行排序,占一行;平均成绩与总成绩用空格分隔,占一行,平均成绩保留两位小数。输入具体格式见样例。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

struct student {
	char ID[21], Name[21];
	int Score[5];
	int total;
	double average;
};
typedef struct student student;

void print(student);
void swap(int*, int*);

int main()
{
	student a;
	gets(a.Name);
	gets(a.ID);
	a.total=0;
	For(i, 0, 4)
	{
		scanf("%d", &a.Score[i]);
		a.total += a.Score[i];
	}
	a.average = a.total / 5.0;
	bool flag;
	for (int i = 3; i >= 0; i--)
	{
		flag = true;
		For(j, 0, i)
			if (a.Score[j] < a.Score[j + 1])
			{
				swap(&a.Score[j], &a.Score[j + 1]);
				flag = false;
			}
		if (flag == true)
			break;
	}
	print(a);
	return 0;
}

void swap(int* a, int* b)
{
	int t = *a;
	*a = *b;
	*b = t;
}

void print(student a)
{
	printf("Name:");
	puts(a.Name);
	printf("ID:");
	puts(a.ID);
	printf("Score:");
	For(i, 0, 4)
		printf("%d ", a.Score[i]);
	printf("\naverage:%.2f total:%d", a.average, a.total);
}
/*
Liu Mengmeng
0821131666666
88 90 93 91 85
*/

PS:结构体基础,因为大家也都是初学者 (其实是懒) 就打了个冒泡
打这个题的时候DEVcpp又双叒叕崩了!十分不爽,懒得吐槽

D.

有n名学生,每个学生的信息包括姓名、学号、5门课程的成绩,平均成绩与总成绩。已知学生的姓名、学号与5门课程的成绩,你的任务是计算每个学生的平均成绩与总成绩,并将它们输出。学生的姓名中只能包含大小写字母与空格字符,不会超过20个字符;学生的学号是个长度不会超过20的字符串,只包含数字字符;课程成绩均为0—100的整数。
要求:在本题中,你要设计一个结构来存储一个学生的信息。在此结构中,需要有一个字符数组来存储姓名;一个字符数组来存储学号;一个长度为5的整型数组来存储5门课程的成绩;一个双精度浮点型变量存储平均成绩,一个整型变量存储总成绩。然后,你要设计一个结构数组来存储n名学生的信息。
输入与输出要求:输入首先是一个正整数n,代表学生的数量,1<=n<=100;每名学生的信息按照姓名、学号、5门课程成绩的顺序输入,共占三行。 输出n名学生的信息:姓名占一行;学号占一行;5门课程成绩中间用空格分开,最后一个成绩后是换行符,占一行;平均与总成绩用空格分隔,占一行,平均成绩保留两位小数;每名同学的信息后都再输出一个空行。输入具体格式见样例。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

struct student {
	char ID[21], Name[21];
	int Score[5];
	int total;
	double average;
};
typedef struct student student;

void print(student);
void swap(int*, int*);

int main()
{
	int n;
	scanf("%d",&n);
	getchar();
	student a[n];
	For(t,0,n-1)
	{
		gets(a[t].Name);
		gets(a[t].ID);
		a[t].total=0;
		For(i, 0, 4)
		{
			scanf("%d", &a[t].Score[i]);
			a[t].total += a[t].Score[i];
		}
		a[t].average = a[t].total / 5.0;
		getchar();
	}
	For(t,0,n-1)
	{
		print(a[t]);
		printf("\n");
	}
	return 0;
}

void swap(int* a, int* b)
{
	int t = *a;
	*a = *b;
	*b = t;
}

void print(student a)
{
	printf("Name:");
	puts(a.Name);
	printf("ID:");
	puts(a.ID);
	printf("Score:");
	For(i, 0, 4)
		printf("%d ", a.Score[i]);
	printf("\naverage:%.2f total:%d\n", a.average, a.total);
}
/*
4
小王同学
0821131699999
87 98 79 90 68
Liu Mengmeng
0821131666666
88 90 93 91 85
Albert Einstein
0821131477777
75 87 100 66 64
Bill Gates
0821131588888
65 58 77 60 61
*/

PS:我感觉这个题比C题简单呀?还是那个问题,记得getchar

E.

有n名学生,每个学生的属性包括姓名与总成绩。已知学生的姓名与总成绩,你的任务是将学生的信息按照以下方式排序:首先比较总成绩,总成绩高的在前面,总成绩低的在后面,当总成绩相同时,你要比较学生的姓名,姓名字典序小的同学在前面,姓名字典序大的同学在后面(ASCII码顺序)。n的范围是1—100;学生的姓名中只能包含大小写字母,不会超过20个字符;总成绩为整数。
要求:在本题中,你要设计一个结构来存储学生的信息。在此结构中,需要有一个字符数组来存储姓名,一个整型变量存储总成绩。
输入与输出要求:首先输入一个正整数n,代表学生的数量,1<=n<=100;每名学生的信息按照姓名、总成绩的顺序输入(空格分开),每名学生信息占一行。输出:n名学生的信息,姓名占一行,总成绩占一行,输出顺序要按照题目的要求,每名同学的信息后都再输出一个空行。输入具体格式见样例。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

struct student {
	char Name[21];
	int total;
};
typedef struct student student;

bool cmp(char*, char*);
int max(int, int);
void print(student);

int main()
{
	int n;
	scanf("%d",&n);
	student a[n+1];
	For(i,0,n-1)
	{
		scanf("%s",a[i].Name);
		scanf("%d",&a[i].total);
	}
	For(i,1,n)
	{
		int maxn=0, p=0;
		For(j,0,n-1)
		{
			if (a[j].total>=maxn)
			{
				if (a[j].total>maxn)
				{
					maxn=a[j].total;
					p=j;
				}
				else if (!cmp(a[j].Name,a[p].Name))
					{
						maxn=a[j].total;
						p=j;
					}
			}
		}
		print(a[p]);
		a[p].total=0;
	}
	return 0;
}

int max(int a, int b)
{
	return a>b?a:b;
}

bool cmp(char *a, char *b)
{
	int len=max(strlen(a), strlen(b));
	For(i,0,len)
	{
		if (a[i]>b[i])
			return true;
		else if (a[i]<b[i])
			return false;
	}
}

void print(student a)
{
	printf("Name:");
	puts(a.Name);
	printf("total:%d\n",a.total);
	printf("\n");
}
/*
4
AlbertEinstein 1328
GeorgeWalkerBush 860
LiuMengmeng 1475
BillGates 1328
*/

PS:这次有点偷懒,没排序,就每次输出分数最高的,如果有分数相同就开始比字典序,感觉难度也没有A、B题大
盘点这次练习里常用的套路:

  • 字符串比较
bool cmp(char *a, char *b)
{
	int len=max(strlen(a), strlen(b));
	For(i,0,len)
	{
		if (a[i]>b[i])
			return true;
		else if (a[i]<b[i])
			return false;
	}
}

算法也很简单,暴力比一遍,有结果就提前终止
前串大则为true,小则为false(没有等于)

  • 冒泡排序
bool flag;
for (int i = n-1; i >= 0; i--)
{
	flag = true;
	For(j, 0, i)
		if (前项 < 后项)//自行改为函数条件
		{
			swap(前项 , 后项);//交换两项
			flag = false;
		}
	if (flag == true)
		break;
}

这是在[0,n]区间上排序的情况,如果是更常见的[0,n)的情况下,需要将i = n-1改为n-2
冒泡排序是一个很容易证明其正确性(数学归纳法),并且兼容性很好的算法,可用于各种排序

第十三次练习

这次的题和往次练习的重复度很大,大概也是希望我们手熟,所以直接交以前的代码是可耻的哦~

A.数组查找(指针)

这个题就是之前打过的题吧!?但是这次我使用指针重新打的
(不要犯开头所述的低级错误)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

int find(int *a, int k, int n) 
{
    For(i,0,n-1)
    	if (a[i]==k)
    		return i;
    return -1;
}

int main()
{
	int n,m,k;
	scanf("%d",&n);
	int a[n];
	For(i,0,n-1)
		scanf("%d",&a[i]);
	scanf("%d",&m);
	For(i,0,m-1)
	{
		scanf("%d",&k);
		int ans=find(a,k,n);
		if (n==1)
			printf("NULL\n");
		else
			if (ans!=-1)
			{
				if (ans==0)
					printf("%d\n",a[1]);
				else if (ans==n-1)
					printf("%d\n",a[n-2]);
				else
					printf("%d %d\n",a[ans-1],a[ans+1]);
			}
			else
				printf("NULL\n");
	}
	return 0;
}
/*
5
89 7890 22 56 87
6
89 7890 22 56 87 999
*/

B.字符删除

同理,这次认真打的,上次打的不是按题目要求来的,应该还羞耻地放在了前几次博客里……

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

void delchar(char *s, char c)
{
	int len=strlen(s)-1;
	For(i,0,len)
	{
		if (s[i]==c)
		{
			For(j,i,len)
				s[j]=s[j+1];
			i--;
		}
	}
}

int main()
{
	char s[101];
	char c;
	gets(s);
	scanf("%c",&c);
	delchar(s,c);
	puts(s);
	return 0;
}
/*
abcABCabc#
b
*/

C.二分查找(动态分配内存)

又是打过的题,但是这次加上malloc和free(我也有重打了一遍)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

int bs(int *a, int k, int n)
{
	int l=0, r=n;
    while(l<r)
    {
        int mid=(l+r)>>1;
        (a[mid]>k)?r=mid:l=mid+1;
    }
    return (int)--l;
}

int main()
{
	int n,m,k;
	scanf("%d%d",&n,&m);
	int *a;
	a=(int*)malloc(sizeof(int)*n);
	For(i,0,n-1)
		scanf("%d",&a[i]);
	For(i,0,m-1)
	{
		scanf("%d",&k);
		int ans=bs(a,k,n);
		if (a[ans]==k)
			printf("%d ",ans);
		else
			printf("-1 ");
	}
	free(a);
	return 0;
}
/*
15 
20
-293 -213 -23 0 1 5 11 23 56 67 87 273 999 2132 10000
-23 -99999 0 999 953 67 56 44 33 87 -293 23 11 273 -213 2132 10000 87654 1 5
*/

D.世界杯

中国队战胜巴西队这种事估计也就在梦里和样例里能出现了……

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

struct team{
	char* name;
	int a,b,c;
	int total;
};
typedef struct team team;

bool cmp(team*, team*);
void swap(team*, team*);
void sort(team*);

int main()
{
	team a[4];
	For(i,0,3)
	{
		a[i].name=(char*)malloc(sizeof(char)*21);
		scanf("%s",a[i].name);
		scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].total);
		a[i].c=a[i].a-a[i].b;
	}
	sort(a);
	For(i,0,3)
		puts(a[i].name);
	return 0;
}

bool cmp(team *a, team *b)		//if a ranks lower than b;
{
	if (a->total>b->total)
		return false;
	else if (a->total<b->total)
		return true;
	else if (a->c>b->c)
		return false;
	else if (a->c<b->c)
		return true;
	else if (a->a>b->a)
		return false;
	else return true;
}

void numswap(int* a, int* b)
{
	int t=*a;
	*a=*b;
	*b=t;
}

void swap(team *a, team *b)
{
	char *t=a->name;
	a->name=(char*)b->name;
	b->name=t;
	numswap(&a->a,&b->a);
	numswap(&a->b,&b->b);
	numswap(&a->c,&b->c);
	numswap(&a->total,&b->total);
}

void sort(team *a)
{
	bool flag;
	for (int i=2; i>=0; i--)
	{
		flag=true;
		For(j,0,i)
			if (cmp(&a[j],&a[j+1]))
			{
				swap(&a[j],&a[j+1]);
				flag=false;
			}
		if (flag==true)
			break;
	}
}
/*
Brazil 3 7 4
China 10 0 9
Germany 4 7 4
Italy 3 6 4
*/

PS:这个题打的并不算漂亮,也调了很久
我觉得结构体swap应该是可以直接赋值的,然而我那样打并不能交换(并不是C++重载了运算符才能赋值)
所以这个问题待解决吧……

  • &a->b也相当于&(a->b),运算符优先级相关~
  • 当然你也可以把他打成(*a).b(看起来就很奇怪)
  • 调试时,输出每次交换的两项,并换行,可以清楚地发现问题
  • 不能很帅地实现,就用笨一点的方法实现(A掉就完了)

E.学生信息管理系统

出现了,大 膜你 模拟!!!(山东的伙伴怀念SDOI名题—>猪国杀 (打死)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define For(i,a,b) for (int i=(a); i<=(b); ++i)

struct student{
	char ID[11], name[11];
	int score[3];
	bool exist;
};
typedef struct student student;

int main()
{
	int n,q,x,y,z;
	scanf("%d",&n);
	student a[n];
	int cnt=-1;
	bool flag;
	char ID[11];
	For(k,1,n)
	{
		scanf("%d",&q);
		switch (q)
		{
			case 1:
				scanf("%s",ID);
				flag=1;
				For(i,0,cnt)
				{
					if (a[i].exist==1 && strcmp(ID,a[i].ID)==0)
					{
						printf("Students already exist\n");
						flag=0;
						scanf("%s %d%d%d",ID,&x,&y,&z);
						break;
					}
				}
				if (flag)
				{
					cnt++;
					int len=strlen(ID);
					For(j,0,len)
					a[cnt].ID[j]=ID[j];
					scanf("%s",a[cnt].name);
					scanf("%d%d%d",&a[cnt].score[0],&a[cnt].score[1],&a[cnt].score[2]);
					a[cnt].exist=1;
					printf("Add success\n");
				}
				break;
			case 2:
				scanf("%s",ID);
				flag=1;
				For(i,0,cnt)
				{
					if (a[i].exist==1 && strcmp(ID,a[i].ID)==0)
					{
						a[i].exist=0;
						printf("Delete success\n");
						flag=0;
						break;
					}
				}
				if (flag)
					printf("Students do not exist\n");
				break;
			case 3:
				scanf("%s",ID);
				flag=1;
				For(i,0,cnt)
				{
					if (a[i].exist==1 && strcmp(ID,a[i].ID)==0)
					{
						scanf("%d%d%d",&a[i].score[0],&a[i].score[1],&a[i].score[2]);
						printf("Update success\n");
						flag=0;
						break;
					}
				}
				if (flag)
				{
					printf("Students do not exist\n");
					scanf("%d%d%d",&x,&y,&z);
				}
				break;
			case 4:
				scanf("%s",ID);
				flag=1;
				For(i,0,cnt)
				{
					if (a[i].exist==1 && strcmp(ID,a[i].ID)==0)
					{
						printf("Student ID:");
						puts(a[i].ID);
						printf("Name:");
						puts(a[i].name);
						printf("Average Score:%.1f\n",(a[i].score[0]+a[i].score[1]+a[i].score[2])/3.0);
						flag=0;
						break;
					}
				}
				if (flag)
					printf("Students do not exist\n");
				break;
		}
//		printf("%10d %d\n",k,q);
	}
	return 0;
}
/*
11
1 201817123 Tom 89 80 76
1 201817123 Tom 89 80 76
1 2019989890 Jerry 78 99 67
4 201817123
2 201817123
3 201817123 79 90 99
2 201817123
4 201817123
4 2019989890
3 2019989890 79 90 99
4 2019989890
*/

PS:你一定发现了下面这组样例并不是OJ上给出的,没错,这正是我自编的,过了这个样例,你就一定能AC了!!(大概)
不得不说我打的好丑……我看着都丑……
如果有时间会把他打成函数,那样不仅从美观上还是从调试上都会好很多(注释掉的那行就是被我拿来调试的)
话不多说,本题注意点:

  • 注意如果该学生不存在,应该吸收其余垃圾信息,即使你已经完成了判断
  • 如果有一行输出结果不对,之后都不对(或者从某行又开始对了),检查上一行操作是否完全吸收
  • 在这种大一点的程序里犯开头所述的几种错误,会让你几轮debug以后极其痛苦,发现错误以后觉得自己是zz 痛改前非,养成良好的代码习惯
    在我打的时候,我发现这道题有一个经典模式:(代码相似度太高<—很垃圾的代码的特征)
scanf("%s",ID);
flag=1;
For(i,0,cnt)
{
	if (a[i].exist==1 && strcmp(ID,a[i].ID)==0)
	{
		//成功的那一部分操作
		flag=0;
		break;
	}
}
if (flag)
{
	printf("Students do not exist\n");
	//失败之后的操作
}
break;

也可以不用exist这个bool型变量来存储这个学生是否存在,可以直接把他的学号的首个字符改为'\0'真 · 你号没了

最后,由于这学期没有讲什么高端算法,留一个二分模板吧!
(亲测洛谷,leetcode上实用)

template <typename T>static Rank biSearch(T *a, T const &k, Rank lo, Rank hi)
{
    while(lo < hi)
    {
        Rank mid = ( lo + hi ) >> 1;
        ( a[mid] > k ) ? r=mid : l=mid+1;
    }
    return --lo;
}

该函数返回不大于k的元素的最大秩
也想写一个关于二分思想的题型blog (两周前就在写了)
二分也并没有想的那样简单

正如Donald Ervin Knuth(KMP算法发明者,与Edsger Wybe Dijkstra并称为当代最伟大的计算机科学家)所说:
Although the basic idea of binary search is comparatively straightforward,
the details can be surprisingly tricky…
作者:labuladong
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-suan-fa-xi-jie-xiang-jie-by-labula/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

update

有一部分电脑不能在终端Ctrl+V直接粘贴样例,导致调试时需要手打,很麻烦
准备:如果你是Ctrl+N直接开了一个.cpp文件的话,那么你实际上就是在C++里打C语言,可以使用C++特性
如果你保存的是.c文件,可以在调试时先改成.cpp(C语言文件读写太麻烦了)
操作步骤:①在你要调试的代码所在的文件夹新建一个文本文档(.txt),建议命名为in
②在main函数的开头加上如下代码:

freopen("in.txt","r",stdin);

再在main函数的末尾加上如下代码:

fclose(stdin);

③只需要在你的in.txt的文本文档里粘贴上样例,然后运行时就会自动输出啦!
当然你也可以:(请无视以下内容)

/*预处理指令部分*/
#define DEBUG
/*主函数部分*/
int main()
{
	#ifdef DEBUG
	freopen("in.txt","r",stdin);
	#endif
	/*实现你的代码*/
}

然后提交时把#define DEBUG删除或者注释掉就行了
(那为什么不直接删掉那两行呢)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值