C语言笔试题整理2

1、C-阿里巴巴找黄金宝箱(III)-一贫如洗的樵夫阿里巴巴在去砍柴的路上

题目描述:

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从 0~N 的箱子,每个箱子上面贴有一个数字。

阿里巴巴念出一个咒语数字,查看宝箱是否存在两个不同箱子,这两个箱子上贴的数字相同,同时这两个箱子的编号之差的绝对值小于等于咒语数字,

如果存在这样的一对宝箱,请返回最先找到的那对宝箱左边箱子的编号,如果不存在则返回-1。

输入描述:

第一行输入一个数字字串,数字之间使用逗号分隔,例如: 1,2,3,1 字串中数字个数>=1,<=100000;每个数字值>=-100000,<=100000;

第二行输入咒语数字,例如:3,咒语数字>=1,<=100000

输出描述:

存在这样的一对宝箱,请返回最先找到的那对宝箱左边箱子的编号,如果不存在则返回-1

补充说明:

题解思路

c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() 
{
	setbuf(stdout, NULL);
	int nums[100000] = {0};
	int len = 0;
	do {
		scanf("%d", &nums[len++]);
	} while (getchar() != '\n');
	
	int val;
	scanf("%d", &val);
	
	int left = 0, right = 1;
	while (left < len)
	{
		if (nums[left] != nums[right] && right -left <= val) 
		{
			right++;
		} 
		else if (nums[left] == nums[right] && right -left <= val)
		 {
			printf("%d ", left);
			return 0;
		} 
		else 
		{
			left++, right = left + 1;
		}
}
	printf("-1");
	return 0;
}

相关代码解析

程序输出有两种方式:一种是即时处理方式,另一种是先暂存起来,然后再大块写入的方式,前者往往造成较高的系统负担。因此,c语言实现通常都允许程序员进行实际的写操作之前控制产生的输出数据量。

这种控制能力一般是通过库函数setbuf实现的。如果buf是一个大小适当的字符数组,那么:

c 复制代码
setbuf(stdout,buf);

语句将通知输入/输出库,所有写入到stdout的输出都应该使用buf作为输出缓冲区,直到buf缓冲区被填满或者程序员直接调用fflush(译注:对于由写操作打开的文件,调用fflush将导致输出缓冲区的内容被实际地写入该文件),buf缓冲区中的内容才实际写入到stdout中。缓冲区的大小由系统头文件<stdio.h>中的BUFSIZ定义。

举例说明如下(代码通过VS2008编译)

cpp 复制代码
#include <iostream>
#include<fstream>

int main(int argc, char* argv[])
{
    char* outbuf =  new char [100];
    setbuf(stdout,outbuf);//将输出流绑定到outbuf上
    puts("helloworld\n");//内容输入到outbuf内
    //setbuf(stdout,NULL);//如果启用这行代码,输出流恢复原来的状态,puts输出到控制台
    delete[] outbuf;
    system("pause");
    return 0;

}

版权声明:本文为CSDN博主「王教余」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/wangjiaoyu250/article/details/8629136

2、C-判断字符串子序列

题目描述:

给定字符串 target 和 source, 判断 target 是否为 source 的子序列。

你可以认为 target 和 source 中仅包含英文小写字母。字符串 source 可能会很长(长度 ~= 500,000),而 target 是个短字符串(长度 <=100)。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位

置形成的新字符串。(例如,"abc"是"aebycd"的一个子序列,而"ayb"不是)。

请找出最后一个子序列的起始位置。

输入描述:

第一行为 target,短字符串(长度 <=100)

第二行为 source,长字符串(长度 ~= 500,000)

输出描述:

最后一个子序列的起始位置, 即最后一个子序列首字母的下标

补充说明:

若在 source 中找不到 target,则输出-1

示例 1

输入:

abc

abcaybec

输出:

3

说明:

这里有两个 abc 的子序列满足,取下标较大的,故返回 3

c 复制代码
#include <stdio.h>
#include <string.h>
int main()
{
	int a = 0;
	int b = 0;
	int c,d;
	
	char chang[500001];
	char duan[101];
	
	scanf("%s",duan);
	scanf("%s",chang);
	c = strlen(chang);
	d = strlen(duan);
	c=c-1;
	d=d-1;
	if(c<d)
	{
		printf("-1");
		return 0;
	}
	if(d==0)
	{
		printf("%d",c);
		return 0;
	}
	while(c!=-1)
	{
		if(chang[c]==duan[d])
		{
			if(d == 0)
			{
				printf("%d",c);
				return 0;
			}
			else
			{
				c--;
				d--;
			}
	}
	else
	{
		c--;
	}
}
	printf("-1");
	return 0;
}

3、给定非空字符串 s,将该字符串分割成一些子串,使每个子串的 ASCII 码值的和均为水仙花数。

1、若分割不成功,则返回 0

2、若分割成功且分割结果不唯一,则返回-1

3、若分割成功且分割结果唯一,则返回分割后子串的数目

输入描述:

1、输入字符串的最大长度为 200

输出描述:

根据题目描述中情况,返回相应的结果

补充说明:

"水仙花数"是指一个三位数,每位上数字的立方和等于该数字本身,如 371 是"水仙花数",

因为:371 = 3^3 + 7^3 + 1^3

示例 1

输入:

abc

输出:

0

说明:

分割不成功

示例 2

输入:

f3@d5a8

输出:

-1

说明:

分割成功但分割结果不唯一,可以分割为两组,一组"f3"和"@d5a8",另外一组"f3@d5" 和"a8" 示例 3

输入:

AXdddF

输出:

2

说明:

成功分割且分割结果唯一,可以分割"AX"(153)和"dddF"(370)成两个子串

c 复制代码
#include <stdio.h>
#include <string.h>

int resCnt = 0;
int resVal = 0;
int resVal1 = 0;
int check(const char *p, int len, int begin, int end) 
{
	int t = 0;
	for (int i = begin; i <= end; i++) 
	{
		t += p[i];
	}
	return t == 370 || t == 153 || t == 407 || t == 371;
}

void test(const char *p, int len, int pos) 
{
	if (pos == len) 
	{
		++resCnt;
		resVal = resVal1;
		return;
	}
	for (int i = pos; i < len; i++) 
	{
		if (check(p, len, pos, i)) 
		{
			++resVal1;
			test(p, len, i + 1);
			resVal1--;
		}
	}
}

int main() 
{
	char str[256] = { 0 };
	scanf("%s", str);
	test(str, strlen(str), 0);
	if (resCnt == 0) 
	{
		printf("0\n");
	}
	else if (resCnt > 1) 
	{
		printf("-1\n");
	}
	else 
	{
		printf("%d\n", resVal);
	}
	return 0;
}

4、勾股数元组题目描述:

如果 3 个正整数(a,b,c)满足 aa + b b = c*c的关系,则称(a,b,c)为勾股数(著名的勾三股四

弦五),为了探索勾股数的规律,我们定义如果勾股数(a,b,c)之间两两互质(即 a 与 b,a

与 c,b 与 c 之间均互质,没有公约数),则其为勾股数元祖(例如(3,4,5)是勾股数元祖,

(6,8,10)则不是勾股数元祖)。请求出给定范围[N,M]内,所有的勾股数元祖。

输入描述:

起始范围 N,1 <= N <= 10000

结束范围 M,N < M <= 10000

输出描述:

  1. a,b,c 请保证 a < b < c,输出格式:a b c;
  2. 多组勾股数元祖请按照 a 升序,b 升序,最后 c 升序的方式排序输出;
  3. 给定范围中如果找不到勾股数元祖时,输出"NA"。

题目描述:

如果 3 个正整数(a,b,c)满足 aa + b b = c*c的关系,则称(a,b,c)为勾股数(著名的勾三股四

弦五),为了探索勾股数的规律,我们定义如果勾股数(a,b,c)之间两两互质(即 a 与 b,a

与 c,b 与 c 之间均互质,没有公约数),则其为勾股数元祖(例如(3,4,5)是勾股数元祖,

(6,8,10)则不是勾股数元祖)。请求出给定范围[N,M]内,所有的勾股数元祖。

输入描述:

起始范围 N,1 <= N <= 10000

结束范围 M,N < M <= 10000

输出描述:

  1. a,b,c 请保证 a < b < c,输出格式:a b c;
  2. 多组勾股数元祖请按照 a 升序,b 升序,最后 c 升序的方式排序输出;
  3. 给定范围中如果找不到勾股数元祖时,输出"NA"。
c 复制代码
#include <stdio.h>
#include <math.h>
int sign = 0;

int checkgcd(int n,int m)
{
	if (n==0||m==0) 
	{
		return 1;
	}
	if (n%m==0) 
	{
		return m;
	}
	else 
	{
		return checkgcd(m, n%m);
	}
}

int getgougushu(int n,int m)
{
	int i,j,k;
	double temp;
	long cz;
	for (i=n; i<=m; i++) 
	{
		for (j=i+1; j<=m; j++) 
		{
			k=i*i+j*j;
			temp=sqrt(k);
			cz=(long)temp;
			if (cz-temp!=0) 
			{
				continue;
			}
			k=(int)temp;
			if(k<=m&&checkgcd(i,j)==1&&checkgcd(i,k)==1&&checkgcd(j,k)==1) 
			{
				printf("%d %d %d\n",i,j,k);
				sign=1;
			}
		}
	}
	return 0;
}

int main() 
{
	int m, n;
	scanf("%d %d", &n, &m);
	getgougushu(n,m);
	if (sign==0) 
	{
		printf("NA\n");
	}
	return 0;
}

5、C-观看文艺汇演问题

题目描述:

为庆祝中国共产党成立 100 周年,某公园将举行多场文艺汇演,很多演出都是同时进行。

一个人只能同时观看一场演出,且不能迟到早退。由于演出分散在不同的演出场地,所以连

续观看的演出最少要有 15 分钟的时间间隔。

小明是一个狂热的文艺迷,想观看尽可能多的演出。现给出演出时间表,请帮小明计算他最

多能观看几场演出。

输入描述:

第一行为一个数 N,表示演出场数,1<=N<=1000

接下来 N 行,每行两个空格分隔的整数,第一个整数 T 表示演出开始时间,第二个整数 L

表示演出持续时间。T 和 L 的单位都是分钟,0<=T<=1440,0<L<=180

输出描述:

请输出最多能观看的演出场数

补充说明:

示例 1

输入:

2

720 120

840 120

输出:

1

说明:

两场演出间隔时间为 0,不满足最小 15 分钟时间间隔的要求,所以最多只能观看一场演出

示例 2

输入:

2

0 60

90 60

输出:

2

说明:

c 复制代码
两场演出间隔大于 15 分钟,都能观看到
#include <stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct time{
int fr,end;
}timer;
timer arr[1010];

int cmp(const void *a,const void *b)
{
	timer *x = (timer*)a;
	timer *y = (timer*)b;
	if(x->end!= y->end)
	{
		return x->end - y->end;
	}
	return x->fr - y->fr;
}

int main() 
{
	int n;
	scanf("%d",&n);
	for(int i = 0;i< n;i++)
	{
		scanf("%d%d",&arr[i].fr,&arr[i].end);
		arr[i].end+=arr[i].fr;
	}
	qsort(arr,n,sizeof(timer),cmp);
	
	int sum = 0;
	int last = -15;
	for(int i = 0;i< n;i++)
	{
		if(arr[i].fr-last>=15)
		{
			sum++;
			last = arr[i].end;
		}
	}
	printf("%d",sum);
	return 0;
}

6、C-最长方连续方波信号

c 复制代码
#include <stdio.h>
#include <string.h>

int main() 
{
	int c;
	int max = 0;
	char data[1025];
	scanf("%s",data);
	c = strlen(data);
	
	int i = 0;
	int j = 0;
	int flag = 0;
	int h = 0;
	int num = 0;
	int search(char data[],int i,int flag,int h);
	for(j=0;j<c;j++)
	{
		num=search(data,j,flag,h);
		if(num>=3&&num>max)
		{
			max = num;
		}
		flag = 0;
	}
	if(max == 0)
	{
		printf("-1");
		return 0;
	}
	else 
	{
		for(j=0;j<max;j++)
		{
			if(j%2 == 0)
			{
				printf("0");
			}
			else 
			{
				printf("1");
			}
		}
	}
	return 0;
}

int search(char data[],int i,int flag,int h)
{
	if(flag == 0)
	{
		if(data[i] =='0')
		{
			i++;
			h++;
			flag = 1;
			h=search(data, i,flag,h);
		}
		else 
		{
			h = 0;
			return h;
		}
	}
	else 
	{
		if(data[i] =='1')
		{
			i++;
			h++;
			flag = 0;
			h=search(data, i,flag,h);
		}
	else 
	{
		return h;
	}	
}
	return h;
}

7、矩形相交的面积

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

int main() 
{
	int matrix[3][4];
	int i,j;
	for (i=0; i<3; i++) 
	{
		for (j=0; j<4; j++) 
		{
			scanf("%d",&matrix[i][j]);
		}
	}
	int x[6],y[6];
	int count=0;
	for (i=0; i<3; i++) 
	{
		x[count] = matrix[i][0];
		y[count] = matrix[i][1];
		count++;
		x[count] = matrix[i][0]+matrix[i][2];
		y[count] = matrix[i][1]-matrix[i][3];
		count++;
	}
	
	int cn1;
	for (i=0; i<6; i++)
		for (j=i+1; j<6; j++) 
		{
			if (x[i]>x[j]) 
			{
				cn1=x[i];
				x[i]=x[j];
				x[j]=cn1;
			}
			if (y[i]>y[j]) 
			{
				cn1=y[i];
				y[i]=y[j];
				y[j]=cn1;
			}
		}
	if(x[2]>=matrix[0][0]&&x[2]>=matrix[1][0]&&x[2]>=matrix[2][0]&&x[3]<=matrix[0][0]+matrix[0][2]&&x[3]<=matrix[1][0]+matrix[1][2]&&x[3]<=matrix[2][0]+matrix[2][2]&&y[3]<=matrix[0][1]&&y[3]<=matrix[1][1]&&y[3]<=matrix[2][1]&&y[2]>=matrix[0][1]-matrix[0][3]&&y[2]>=matrix[1][1]-matrix[1][3]&&y[2]>=matrix[2][1]-matrix[2][3]) 
	{
		printf("%d",(x[3]-x[2])*(y[3]-y[2]));
	}
	else 
	{
		printf("0");
	}
}

8、题目描述:

停车场有一横排车位,0 代表没有停车,1 代表有车。至少停了一辆车在车位上,也至少

有一个空位没有停车。

为了防剐蹭,需为停车人找到一个车位,使得距停车人的车最近的车辆的距离是最大的,返

回此时的最大距离。

输入描述:

1、一个用半角逗号分割的停车标识字符串,停车标识为 0 或 1,0 为空位,1 为已停车。

2、停车位最多 100 个。

输出描述:

输出一个整数记录最大距离。

示例 1

输入:

1,0,0,0,0,1,0,0,1,0,1

输出:

2

说明:

当车停在第 3 个位置上时,离其最近的的车距离为 2(1 到 3)。

当车停在第 4 个位置上时,离其最近的的车距离为 2(4 到 6)。

其他位置距离为 1。

因此最大距离为 2。

c 复制代码
#include "stdio.h" 
#include "stdlib.h" 
#include "string.h" 
#define MAX 101

int main()
{
	int n = 0,i, j, sum = 0, max=0, flag = 0;
	int num[MAX];
	do{
		scanf("%d", &num[n++]);
	}while(getchar() != '\n');
	
	for(i=0; i<n; i++)
	{
		if(num[i] == 1)
		{
			sum = 0;
			flag = 1;
		}
		else sum++;
		if(flag == 0)
			if(max < sum)
				max = sum;
		if(flag == 1)
			if(max < (sum+1)/2)
				max = (sum+1)/2;
		//printf("%d ",sum);
		//printf("%d ",max);
	}
	flag = 0;
	sum = 0;
	for(i=n-1; i>0; i--)
	{
		if(num[i] == 1)
		{
			sum = 0;
			flag = 1;
		}
	else sum++;
	if(flag == 0)
		if(max < sum)
			max = sum;
	if(flag == 1)
		if(max < (sum+1)/2)
			max = (sum+1)/2;
	//printf("%d ",sum);
	//printf("%d ",max);
	}
	printf("%d",max);
	return 0;
}

9、支持优先级的队列题目描述:

实现一个支持优先级的队列,高优先级先出队列;同优先级时先进先出。

如果两个输入数据和优先级都相同,则后一个数据不入队列被丢弃。

队列存储的数据内容是一个整数。

输入描述:

一组待存入队列的数据(包含内容和优先级)

输出描述:

队列的数据内容(优先级信息输出时不再体现)

补充说明:

不用考虑输入数据不合法的情况,测试数据不超过 100 个

示例 1

输入:

(10,1),(20,1),(30,2),(40,3)

输出:

40,30,10,20

说明:

输入样例中,向队列写入了 4 个数据,每个数据由数据内容和优先级组成。

输入和输出内容都不含空格。

数据 40 的优先级最高,所以最先输出,其次是 30;10 和 20 优先级相同,所以按输入

顺序输出。

示例 2

输入:

(10,1),(10,1),(30,2),(40,3)

输出:

40,30,10

说明:

输入样例中,向队列写入了 4 个数据,每个数据由数据内容和优先级组成。

输入和输出内容都不含空格。

数据 40 的优先级最高,所以最先输出,其次是 30;两个 10 和 10 构成重复数据,被丢

弃一个。

c 复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct {
	int a;
	int b;
} item;

int cmp(const void *x, const void *y) 
{
	return ((item *) y)->b - ((item *) x)->b;
}

int main() 
{
	char str[200] = {0};
	gets(str);
	int len = strlen(str);
	char tgt[200] = {0};
	int tgt_size = 0;
	for (int i = 0; i < len; ++i) 
	{
		if (str[i] == '(' || str[i] == ')') 
		{
			continue;
		}
		tgt[tgt_size++] = str[i];
	}

	char *queues[200] = {0};
	int queues_size = 0;
	char *tok = strtok(tgt, ",");

	while (tok != NULL) 
	{
		queues[queues_size++] = tok;
		tok = strtok(NULL, ",");
	}

	item items[200] = {0};
	int item_size = 0;

	for (int i = 0; i < queues_size; i += 2) 
	{
		int a = atoi(queues[i]);
		int b = atoi(queues[i + 1]);
		bool flag = false;
		for (int j = 0; j < item_size; ++j) 
		{
			if (items[j].a == a && items[j].b == b) 
			{
				flag = true;
				break;
			}
		}
		if (!flag) 
		{
			items[item_size].a = a;
			items[item_size].b = b;
			item_size++;
		}
	}
	
	qsort(items, item_size, sizeof(item), cmp);
	int res[1000] = {0};
	int m = 0;
	for (int i = 0; i < queues_size; ++i) 
	{
		if(items[i].a != 0)
		{
			res[m++] = items[i].a;
		}
	}
	
	for(int i = 0; i < m - 1; ++i)
	{
		printf("%d,", res[i]);
	}
	printf("%d", res[m - 1]);
	return 0;
}

10、题目描述:

给定一个正整型数组表示待系统执行的任务列表,数组的每一个元素代表一个任务,元素的

值表示该任务的类型。请计算执行完所有任务所需的最短时间。任务执行规则如下:

1、任务可以按任意顺序执行,且每个任务执行耗时间均为 1 个时间单位。

2、两个同类型的任务之间必须有长度为 N 个单位的冷却时间,比如:N 为 2 时,在时间

K 执行了类型 3 的任务,那么 K+1 和 K+2 两个时间不能执行类型 3 任务。

3、系统在任何一个单位时间内都可以执行一个任务,或者等待状态。

说明:数组最大长度为 1000,数组最大值 1000. 输入描述:

第一行记录一个用半角逗号分隔的数组,数组长度不超过 1000,数组元素的值不超过

1000

第二行记录任务冷却时间,N 为正整数,N<=100。

输出描述:

输出为执行完所有任务所需的最短时间。

补充说明:

示例 1

输入:

2,2,2,3

2

输出:

7

说明:

时间 1:执行类型 2 任务。

时间 2:执行类型 3 的任务(因为冷却时间为 2,所以时间 2 不能执行类型 2 的任务)。

时间 3:系统等待(仍然在类型 2 的冷却时间)。

时间 4:执行类型 2 任务。

时间 5:系统等待。

时间 6:系统等待。

时间 7:执行类型 2 任务。

因此总共耗时 7。

c 复制代码
#include <stdio.h>
#include <math.h>
#define MAXSIZE 1001

int main() 
{
	int arr[MAXSIZE];
	int arrLen = 0;
	do {
		scanf("%d", &arr[arrLen++]);
	} while (getchar() != '\n');
	
	int k;
	scanf("%d", &k);
	int height = 0;
	int cnt = 0;
	int cache[MAXSIZE] = {0};
	for (int i = 0; i < arrLen; ++i) 
	{
		cache[arr[i]]++;
		height = height < cache[arr[i]] ? cache[arr[i]] : height;
	}
	for (int i = 0; i < MAXSIZE; ++i) 
	{
		if (height == cache[i]) 
		{
			++cnt;
		}
	}
	if (height == 1) 
	{
		printf("%d\n", arrLen);
		return 0;
	}
	printf("%d", (int) fmax(arrLen, (k + 1) * (height - 1) + cnt));
	return 0;
}

11、数字游戏题目描述:

小明玩一个游戏。系统发 1+n 张牌,每张牌上有一个整数。第一张给小明,后 n 张按照发牌

顺序排成连续的一行。需要小明判断,后 n 张牌中,是否存在连续的若干张牌,其和可以整

除小明手中牌上的数字。

输入描述:

输入数据有多组,每组输入数据有两行,输入到文件结尾结束。

第一行有两个整数 n 和 m,空格隔开。m 代表发给小明牌上的数字。

第二行有 n 个数,代表后续发的 n 张牌上的数字,以空格隔开。

输出描述:

对每组输入,如果存在满足条件的连续若干张牌,则输出 1;否则,输出 0

补充说明:

1 <= n <= 1000

1 <= 牌上的整数 <= 400000

输入的组数,不多于 1000

用例确保输入都正确,不需要考虑非法情况。

示例 1

输入:

6 7

2 12 6 3 5 5

10 11

1 1 1 1 1 1 1 1 1 1

输出:

1

0

说明:

两组输入。第一组小明牌的数字为 7,再发了 6 张牌。第 1、2 两张牌数字和为 14,可以

整除 7,输出 1。第二组小明牌的数字为 11,再发了 10 张牌,这 10 张牌数字和为 10,

无法整除 11,输出 0。

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct data{
	int * nums;
	int numsSize;
	int target;
};

void calc(struct data * arr, int arrLen)
{
	for(int i = 0; i < arrLen; ++i)
	{
		int tmp[1000] = {0};
		int tmpLen = 1;
		int sum = 0;
		int res = 0;
		for(int j = 0; j < arr[i].numsSize; ++j)
		{
			sum += arr[i].nums[j];
			int val = sum % arr[i].target;
			int flag = 0;
			for (int k = 0; k < tmpLen; ++k) 
			{
				if(val == tmp[k])
				{
					flag = 1;
					break;
				}
			}
			if(flag == 1)
			{
				res = 1;
				break;
			}
			else
			{
				tmp[tmpLen++] = val;
			}
		}
		printf("%d\n", res);
	}
}

int main()
{
	int n = 0;
	struct data arr[1000] = {0};
	int arrLen = 0;
	while(scanf("%d", &n) != EOF)
	{
		arr[arrLen].numsSize = n;
		arr[arrLen].nums = (int *)malloc(sizeof(int) * n);
		scanf("%d", &arr[arrLen].target);
		for (int i = 0; i < n; ++i) 
		{
			scanf("%d", &arr[arrLen].nums[i]);
		}
		arrLen++;
	}
	calc(arr, arrLen);
	return 0;
}

12、C-比赛的冠亚季军

题目描述:

有 N(3<=N<10000)个运动员,他们的 id 为 0 到 N-1,他们的实力由一组整数表示。他们之

间进行比赛,需要决出冠亚军。比赛的规则是 0 号和 1 号比赛,2 号和 3 号比赛,以此类推,

每一轮,相邻的运动员进行比赛,获胜的进入下一轮;实力值大的获胜,实力值相等的情况,

id 小的情况下获胜;,轮空的直接进入下一轮. 输入描述:

输入一行 N 个数字代表 N 的运动员的实力值(0<=实力值<=10000000000)。

输出描述:

输出冠亚军的 id,用空格隔开。

补充说明:

示例 1

输入:

2 3 4 5

输出:

3 1 2

说明:

第一轮比赛,id 为 0 实力值为 2 的运动员和 id 为 1 实力值为 3 的运动员比赛, 1 号胜出进

入下一轮争夺冠亚军,id 为 2 的运动员和 id 为 3 的运动员比赛,3 号胜出进入下一轮争夺冠

亚军;冠亚军比赛,3 号胜 1 号;故冠军为 3 号, 亚军为 1 号。2 号与 0 号,比赛进行季军

的争夺,2 号实力值为 4,0 号实力值 2,故 2 号胜出,得季军。冠亚季军为 3 1 2。

c 复制代码
#include <stdio.h>
#include<string.h>

char inp[10000010];

struct peo {
	int index;
	int fen;
} p[100010], q[100010], s, L, s1, L1;

int main() 
{
	gets(inp);
	int now = 0;
	int k = 0;
	for (int i = 0; i < strlen(inp); i++ ) 
	{
		if (inp[i] == ' ') 
		{
			p[k].fen = now;
			now = 0;
			p[k].index = k;
			k++;
		} 
		else 
		{
			now = now * 10 + inp[i] - '0';
		}
	}
	p[k].fen = now;
	p[k].index = k;
	k++;
	while (k > 4) 
	{
		int kk = 0;
		for (int i = 0; i < k; i += 2) 
		{
			if (i + 1 < k) 
			{
				if (p[i].fen >= p[i + 1].fen) 
				{
					q[kk].fen = p[i].fen;
					q[kk].index = p[i].index;
				} 
				else 
				{
					q[kk].fen = p[i + 1].fen;
					q[kk].index = p[i + 1].index;
				}
			} 
			else 
			{
				q[kk].fen = p[i].fen;
				q[kk].index = p[i].index;
			}
			kk++;
		}
		k = kk;
		for (int i = 0; i < k; i++) 
		{
			p[i].fen = q[i].fen;
			p[i].index = q[i].index;
		}
	}
	int G, Y, J;
	if (k == 3) 
	{
		s = p[0].fen >= p[1].fen ? p[0] : p[1];
		L = p[0].fen < p[1].fen ? p[0] : p[1];
		J = L.index;
		G = s.fen >= p[2].fen ? s.index : p[2].index;
		Y = s.fen < p[2].fen ? s.index : p[2].index;
	} 
	else 
	{
		s = p[0].fen >= p[1].fen ? p[0] : p[1];
		L = p[0].fen < p[1].fen ? p[0] : p[1];
		s1 = p[2].fen >= p[3].fen ? p[2] : p[3];
		L1 = p[2].fen < p[3].fen ? p[2] : p[3];
		G = s.fen >= s1.fen ? s.index : s1.index;
		Y = s.fen < s1.fen ? s.index : s1.index;
		J = L.fen >= L1.fen ? L.index : L1.index;
	}
	printf("%d %d %d", G, Y, J);
}

13、C-阿里巴巴找黄金宝箱(I)

题目描述:

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号

从 0~N 的箱子,每个箱子上面贴有一个数字,箱子中可能有一个黄金宝箱。

黄金宝箱满足排在它之前的所有箱子数字和等于排在它之后的所有箱子数字和;第一个箱子

左边部分的数字和定义为 0;最后一个宝箱右边部分的数字和定义为 0。

请帮阿里巴巴找到黄金宝箱,输出第一个满足条件的黄金宝箱编号,如果不存在黄金宝箱,

请返回-1。

输入描述:

箱子上贴的数字列表,使用逗号分隔,例如 1,-1,0。

宝箱的数量不小于 1 个,不超过 10000

宝箱上贴的数值范围不低于-1000,不超过 1000

输出描述:

第一个黄金宝箱的编号

补充说明:

示例 1

输入:

2,5,-1,8,6

输出:

3

说明:

下标 3 之前的数字和为:2 + 5 + -1 = 6

下标 3 之后的数字和为:6 = 6

示例 2

输入:

8,9

输出:

-1

说明:

不存在符合要求的位置

示例 3

输入:

11

输出:

0

说明:

下标 0 之前的数字和为:0

下标 0 之后的数字和为:0

c 复制代码
#include <stdio.h>
#include<string.h>

int main() 
{
	int a;
	int i;
	int k = 0;
	int bag[10001];
	scanf("%d", &a);
	bag[k] = a;
	k++;
	while (getchar() == ',') 
	{
		scanf("%d", &a) ;
		bag[k] = a;
		k++;
	}
	if(k == 1)
	{
		printf("0");
		return 0;
	}
	int num = 0;
	int now = 0;
	for(i = 0;i<k;i++)
	{
		num = num + bag[i];
	}
	i = 0;
	while (i<k) 
	{
		if(now == num - bag[i])
		{
			printf("%d",i);
			return 0;
		}
		else 
		{
			now = now + bag[i];
			num = num - bag[i];
			i++;
		}
	}
	printf("-1");
	return 0;
}

14、C-数列描述

题目描述:

有一个数列 a[N] (N=60),从 a[0]开始,每一项都是一个数字。数列中 a[n+1]都是 a[n]的描述。

其中 a[0]=1。

规则如下:

a[0]:1

a[1]:11(含义:其前一项 a[0]=1 是 1 个 1,即"11"。表示 a[0]从左到右,连续出现了 1 次"1")

a[2]:21(含义:其前一项 a[1]=11,从左到右:是由两个 1 组成,即"21"。表示 a[1]从左到右,

连续出现了两次"1")

a[3]:1211(含义:其前一项 a[2]=21,从左到右:是由一个 2 和一个 1 组成,即"1211"。表示

a[2]从左到右,连续出现了 1 次"2",然后又连续出现了 1 次"1")

a[4]:111221(含义:其前一项a[3]=1211,从左到右:是由一个1、一个2、两个1 组成,即"111221"。

表示 a[3]从左到右,连续出现了 1 次"1",连续出现了 1 次"2",连续出现了两次"1")

请输出这个数列的第 n 项结果(a[n],0≤n≤59)。

输入描述:

数列的第 n 项(0≤n≤59):

4

输出描述:

数列的内容:

111221

补充说明:

示例 1

输入:

4

输出:

111221

说明:

c 复制代码
#include <stdio.h>
#include<string.h>

char zbx_res[100005] = {0};
char zbx_tem[100005] = {0};
char zbx_tem2[100005] = {0};
int p = 0;

int main() 
{
	int n;
	scanf("%d", &n);
	zbx_res[p++] = '1';
	zbx_res[p] = '\0';
	for(int c = 0;c<n;c++)
	{
		int i = 0;
		int m = strlen(zbx_res);
		memset(zbx_tem,0,strlen(zbx_tem));
		while(i<m)
		{
			int j = i+1;
			while(j<m&&zbx_res[j] == zbx_res[i])
			{
				++j;
			}
			sprintf(zbx_tem2,"%d",j-i);
			strcat(zbx_tem,zbx_tem2);
			p = strlen(zbx_tem);
			zbx_tem[p++] = zbx_res[i];
			zbx_tem[p] = '\0';
			i = j;
		}
		strcpy(zbx_res,zbx_tem);
	}
	printf("%s",zbx_res);
	return 0;
}

15、题目描述:

一个有 N 个选手参加比赛,选手编号为 1~N(3<=N<=100),有 M(3<=M<=10)个

评委对选手进行打分。打分规则为每个评委对选手打分,最高分 10 分,最低分 1 分。

请计算得分最多的 3 位选手的编号。如果得分相同,则得分高分值最多的选手排名靠前(10

分数量相同,则比较 9 分的数量,以此类推,用例中不会出现多个选手得分完全相同的情

况)。

输入描述:

第一行为半角逗号分割的两个正整数,第一个数字表示 M(3<=M<=10)个评委,第二个

数字表示 N(3<=N<=100)个选手。

第 2 到 M+1 行是半角逗号分割的整数序列,表示评委为每个选手的打分,0 号下标数字表

示 1 号选手分数,1 号下标数字表示 2 号选手分数,依次类推。

输出描述:

选手前 3 名的编号。

注:若输入为异常,输出-1,如 M、N、打分不在范围内。

示例 1

输入:

4,5

10,6,9,7,6

9,10,6,7,5

8,10,6,5,10

9,10,8,4,9

输出:

2,1,5

说明:

第一行代表有 4 个评委,5 个选手参加比赛

矩阵代表是 4*5,每个数字是选手的编号,每一行代表一个评委对选手的打分排序,

2 号选手得分 36 分排第 1,1 号选手 36 分排第 2,5 号选手 30 分(2 号 10 分值有 3

个,1 号 10 分值只有 1 个,所以 2 号排第一)

示例 2

输入:

2,5

7,3,5,4,2

8,5,4,4,3

输出:

-1

说明:

只有 2 个评委,要求最少为 3 个评委

示例 3

输入:

4,2

8,5

5,6

10,4

8,9

输出:

-1

说明:

只有 2 名选手参加,要求最少为 3 名

示例 4

输入:

4,5

11,6,9,7,8

9,10,6,7,8

8,10,6,9,7

9,10,8,6,7

输出:

-1

说明:

第一个评委给第一个选手打分 11,无效分数

c 复制代码
#include "stdio.h" 
#include "stdlib.h" 
#include "string.h"

typedef struct asf{
	int allscore;
	int num;
}all;

int cmp(const void *a, const void *b)
{
	return *(int*)b-*(int*)a;
}
int cmps(const void *a, const void *b)
{
	return (*(all*)b).allscore-(*(all*)a).allscore;
}
int main() 
{
	int i, j, k, m, n, temp, flag = 0;
	while (scanf("%d,%d", &m, &n) != EOF) 
	{
		if ((m > 10) || (m < 3)) 
		{
			die:printf("-1");
			break;
		}
		if ((n > 100) || (n < 3)) 
		{
			printf("-1");
			break;
		}
		int score[n][m];
		all allscore[n];
		scanf("\n");
		for (i = 0; i < m; i++)
		{
			for (j = 0; j < n; j++)
			{
				scanf("%d,", &score[j][i]);
				//printf("%d,",score[j][i]);
				if ((score[j][i] > 10) || (score[j][i] < 1))
				{
					flag = 1;
				}
			}
			//printf("\n");
		}
		if(flag)
		{
			printf("-1");
			break;
		}
		for (j = 0; j < n; j++)
		{
			qsort(score[j], m, sizeof(int), cmp);
			allscore[j].allscore = 0;
			allscore[j].num = j+1;
			for (i = 0; i < m; i++)
			{
				allscore[j].allscore += score[j][i];
			}
			//printf("%d ",allscore[j].allscore);
		}
		qsort(allscore, n, sizeof(all), cmps);
		//for (k = 0; k < n-1; k++)
		for (i = 0; i < n-1; i++)
		{
			if(allscore[i].allscore == allscore[i+1].allscore)
				for(j = 0; j < m; j++)
				{
					if(score[allscore[i].num - 1][j] > score[allscore[i+1].num - 1][j])
						break;
					else if(score[allscore[i].num - 1][j] == score[allscore[i+1].num - 1][j])
						continue;
					else if(score[allscore[i].num - 1][j] < score[allscore[i+1].num - 1][j])
					{
						temp = allscore[i].num;
						allscore[i].num = allscore[i+1].num;
						allscore[i+1].num = temp;
						temp = allscore[i].allscore;
						allscore[i].allscore = allscore[i+1].num;
						allscore[i+1].allscore = temp;
						break;
					}
				}
				//printf("%d,",allscore[i].num);
				//printf("%d ",allscore[i].allscore);
			}
			for (i = 0; i < 2; i++)
			{
				printf("%d,",allscore[i].num);
				//printf("%d ",allscore[i].allscore);
			}
			printf("%d",allscore[i].num);
			//printf(",%d",allscore[i].allscore);
		}
	return 0;
}

16、题目描述:

TLV 编码是按[Tag Length Value]格式进行编码的,一段码流中的信元用 Tag 标识,Tag 在

码流中唯一不重复,Length 表示信元 Value 的长度,Value 表示信元的值。

码流以某信元的 Tag 开头,Tag 固定占一个字节,Length 固定占两个字节,字节序为小端序。

现给定 TLV 格式编码的码流,以及需要解码的信元 Tag,请输出该信元的 Value。

输入码流的 16 机制字符中,不包括小写字母,且要求输出的 16 进制字符串中也不要包含小

写字母;码流字符串的最大长度不超过 50000 个字节。

输入描述:

输入的第一行为一个字符串,表示待解码信元的 Tag;

输入的第二行为一个字符串,表示待解码的 16 进制码流,字节之间用空格分隔。

输出描述:

输出一个字符串,表示待解码信元以 16 进制表示的 Value。

补充说明:

示例 1

输入:

31

32 01 00 AE 90 02 00 01 02 30 03 00 AB 32 31 31 02 00 32 33 33 01 00

CC

输出:

32 33

说明:

需要解析的信元的 Tag 是 31,从码流的起始处开始匹配,Tag 为 32 的信元长度为 1(01

00,小端序表示为 1);第二个信元的 Tag 是 90,其长度为 2;第三个信元的 Tag 是

30,其长度为 3;第四个信元的 Tag 是 31,其长度为 2(02 00),所以返回长度后面

的两个字节即可,即 32 33。

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
	int tar;
	scanf("%X", &tar);
	char s[50001] = {0};
	getchar();
	gets(s);
	short hexNums[50000] = {0};
	int n = 0;
	char * p = s;
	while(p = strtok(p, " "))
	{
		sscanf(p, "%X", &hexNums[n++]);
		p = NULL;
	}
	int idx = 0;
	while(idx < n)
	{
		int length = (hexNums[idx + 2] << 8) | hexNums[idx + 1];
		if(tar == hexNums[idx])
		{
			for (int i = idx + 3; i < idx + 3 + length - 1; ++i) 
			{
				printf("%02X ", hexNums[i]);
			}
			printf("%02X\n", hexNums[idx + 3 + length - 1]);
			return 0;
		}
		idx += length + 3;
		}
	return 0;
}

17、题目描述:

现在有多组整数数组,需要将它们合并成一个新的数组。合并规则,从每个数组里按顺序取

出固定长度的内容合并到新的数组中,取完的内容会删除掉,如果该行不足固定长度或者已

经为空,则直接取出剩余部分的内容放到新的数组中,继续下一行。

输入描述:

第一行是每次读取的固定长度,0<长度<10

第二行是整数数组的数目,0<数目<1000

第 3-n 行是需要合并的数组,不同的数组用回车换行分隔,数组内部用逗号分隔,最大不

超过 100 个元素。

输出描述:

输出一个新的数组,用逗号分隔。

示例 1

输入:

3

2

2,5,6,7,9,5,7

1,7,4,3,4

输出:

2,5,6,1,7,4,7,9,5,3,4,7

说明:

1、获得长度 3 和数组数目 2。

2、先遍历第一行,获得 2,5,6;

3、再遍历第二行,获得 1,7,4;

4、再循环回到第一行,获得 7,9,5;

5、再遍历第二行,获得 3,4;

6、再回到第一行,获得 7,按顺序拼接成最终结果。

示例 2

输入:

4

3

1,2,3,4,5,6

1,2,3

1,2,3,4

输出:

1,2,3,4,1,2,3,1,2,3,4,5,6

c 复制代码
#include <stdio.h>

long long A[1002][102];
char S[2002];
int indices[1002];
int C[1002];
long long R[100002];

int main()
{
	int i, j;
	int t;
	int L;
	int n;
	int N;
	int sign;
	long long v;
	int count = 0;
	scanf("%d", &L);
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		C[i] = 0;
	}
	for (i = 0; i < n; i++)
	{
		scanf("%s", S);
		sign = 1;
		v = 0;
		for (j = 0; S[j]; j++)
		{
			if (S[j] == ',')
			{
				v /= 10;
				A[i][C[i]] = sign * v;
				sign = 1;
				v = 0;
				C[i]++;
			}
			else
			{
				if (S[j] == '-')
				{
					sign = -1;
				}
				else
				{
					v += S[j] - '0';
					v *= 10;
				}
			}
		}
		v /= 10;
		A[i][C[i]] = sign * v;
		C[i]++;
	}
	N = 0;
	for (i = 0; i < n; i++)
	{
		N += C[i];
	}
	for (i = 0; i < n; i++)
	{
		indices[i] = 0;
	}
	t = 0;
	while (count < N)
	{
		for (i = 0; i < L; i++)
		{
			if (indices[t] == C[t])
			{
				break;
			}
			R[count] = A[t][indices[t]];
			indices[t]++;
			count++;
			if (count == N)
			{
				break;
			}
		}
		t++;
		t %= n;
		}
	if (N)
	{
		printf("%lld", R[0]);
	}
	for (i = 1; i < N; i++)
	{
		printf(",%lld", R[i]);
	}
	return 0;
}

18、题目描述:

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号

从 0~N 的箱子,每个箱子上面贴有一个数字,箱子中可能有一个黄金宝箱。

黄金宝箱满足排在它之前的所有箱子数字和等于排在它之后的所有箱子数字和;第一个箱子

左边部分的数字和定义为 0;最后一个宝箱右边部分的数字和定义为 0。

请帮阿里巴巴找到黄金宝箱,输出第一个满足条件的黄金宝箱编号,如果不存在黄金宝箱,

请返回-1。

输入描述:

箱子上贴的数字列表,使用逗号分隔,例如 1,-1,0。

宝箱的数量不小于 1 个,不超过 10000

宝箱上贴的数值范围不低于-1000,不超过 1000

输出描述:

第一个黄金宝箱的编号

补充说明:

示例 1

输入:

2,5,-1,8,6

输出:

3

说明:

下标 3 之前的数字和为:2 + 5 + -1 = 6

下标 3 之后的数字和为:6 = 6

示例 2

输入:

8,9

输出:

-1

说明:

不存在符合要求的位置

示例 3

输入:

11

输出:

0

说明:

下标 0 之前的数字和为:0

下标 0 之后的数字和为:0

c 复制代码
#include<stdio.h>

int main()
{
	int a[10010];
	int s;
	int n;
	int i=0;
	while(scanf("%d,",&a[i])!=EOF)
	{
		i++;
	}
	/*
	for(int i=0;i<10;i++)
	{
		scanf("%d,",&a[i]);
	}*/
	n=i;
	// printf("i=%d\n",i);
	for(int i=0;i<5;i++)
	{
		//printf("%d ",a[i]);
	}
	
	int left=0;
	int right=0;
	s=0;
	for(int i=0;i<n;i++)
	{
		s=s+a[i];
	}
	//printf("s=%d\n",s);
	if(s-a[0]==0)
	{
		printf("0\n");
		return 0;
	}
	if(s-a[n-1]==0)
	{
		printf("%d\n",n-1);
		return 0;
	}
	left=0;
	right=s-a[0];
	int z=1;
	while(left!=right)
	{
		left=left+a[z-1];
		right=right-a[z];
		//printf("left=%d right=%d z=%d\n",left,right,z);
		z++;
		if(z==n)
		{
			break;
		}
	}
	if(z==n)
	{
		printf("-1\n");
	}
	else
	{
		printf("%d\n",z-1);
	}
	return 0;
}

19、找终点题目描述:

给定一个正整数数组,设为 nums,最大为 100 个成员,求从第一个成员开始,正好走到

数组最后一个成员,所使用的最少步骤数。

要求:

1、第一步必须从第一元素开始,且 1<=第一步的步长<len/2;(len 为数组的长度,需要

自行解析)。

2、从第二步开始,只能以所在成员的数字走相应的步数,不能多也不能少, 如果目标不可

达返回-1,只输出最少的步骤数量。

3、只能向数组的尾部走,不能往回走。

输入描述:

由正整数组成的数组,以空格分隔,数组长度小于 100,请自行解析数据数量。

输出描述:

正整数,表示最少的步数,如果不存在输出-1

示例 1

输入:

7 5 9 4 2 6 8 3 5 4 3 9

输出:

2

说明:

第一步: 第一个可选步长选择 2,从第一个成员 7 开始走 2 步,到达 9;第二步: 从 9

开始,经过自身数字 9 对应的 9 个成员到最后。

示例 2

输入:

1 2 3 7 1 5 9 3 2 1

输出:

-1

说明:

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
	int data[100] = {0};
	int dataSize = 0;
	do {
		scanf("%d", &data[dataSize++]);
	} while (getchar() != '\n');
	
	int dp[dataSize];
	memset(dp, -1, sizeof(dp));
	for (int i = 0; i < dataSize / 2; ++i) 
	{
		int step = 2;
		int index = i;
		dp[i] = 1;
		while (index + data[index] < dataSize) 
		{
			dp[index + data[index]] = step;
			index += data[index];
			step++;
		}
	}
	printf("%d", dp[dataSize - 1]);
	return 0;
}

20、题目描述:

某通信网络中有 N 个网络结点,用 1 到 N 进行标识。网络中的结点互联互通,且结点之间

的消息传递有时延,相连结点的时延均为一个时间单位。

现给定网络结点的连接关系 link[i]={u,v},其中 u 和 v 表示网络结点。

当指定一个结点向其他结点进行广播,所有被广播结点收到消息后都会在原路径上回复一条

响应消息,请计算发送结点至少需要等待几个时间单位才能收到所有被广播结点的响应消息。

注:

1、N 的取值范围为[1,100];

2、连接关系 link 的长度不超过 3000,且 1 <= u,v <= N;

3、网络中任意结点间均是可达的;

输入描述:

输入的第一行为两个正整数,分别表示网络结点的个数 N,以及时延列表的长度 I;

接下来的 I 行输入,表示结点间的连接关系列表;

最后一行的输入为一个正整数,表示指定的广播结点序号;

输出描述:

输出一个整数,表示发送结点接收到所有响应消息至少需要等待的时长。

补充说明:

示例 1

输入:

5 7

2 1

1 4

2 4

2 3

3 4

3 5

4 5

2

输出:

4

说明:

2 到 5 的最小时延是 2 个时间单位,而 2 到其他结点的最小时延是 1 个时间单位,所以 2 收

到所有结点的最大响应时间为 2*2=4。

c 复制代码
#include<stdio.h>
#include<string.h>
int main()
{
	int N,L;
	scanf("%d %d",&N,&L);
	int a[3000][3000];
	int c[3000];
	memset(a,0,sizeof(a));
	int x;
	int y;
	
	for(int i=0;i<L;i++)
	{
		scanf("%d %d",&x,&y);
		c[i]=150*x+y;
		a[x][y]=1;
	}
	for(int i=0;i<N+1;i++)
	{
		for(int j=0;j<N+1;j++)
		{
			// printf("%d ",a[i][j]);
		}
		// printf("\n");
	}
	for(int i=0;i<L;i++)
	{
		// printf("c[%d]=%d\n",i,c[i]);
	}
	int str;
	scanf("%d",&str);
	// printf("str=%d\n",str);
	int b[110];
	int v[110];
	memset(v,0,sizeof(v));
	memset(b,0,sizeof(b));
	b[0]=str;
	v[str]=1;
	int num[110];
	memset(num,0,sizeof(num));
	int s=0;
	int t=1;
	while(s!=t)
	{
		int w=b[s];
		for(int i=0;i<L;i++)
		{
			int tx=c[i]/150;
			int ty=c[i]%150;
			if(tx==w&&ty!=w&&v[ty]==0)
			{
				b[t]=ty;
				v[ty]=1;
				t++;
				num[ty]=num[w]+1;
			}
			if(ty==w&&tx!=w&&v[tx]==0)
			{
				b[t]=tx;
				v[tx]=1;
				t++;
				num[tx]=num[w]+1;
			}
		}
		if(t==N)
		{
			break;
		}
		s++;
	}
	for(int i=0;i<N+1;i++)
	{
		//printf("num[%d]=%d\n",i,num[i]);
	}
	int res=0;
	int max=0;
	for(int i=0;i<N+1;i++)
	{
		res=res>num[i]?res:num[i];
	}
	printf("%d\n",2*res);
	return 0;
}

21、题目描述:

某通信网络中有 N 个网络结点,用 1 到 N 进行标识。网络中的结点互联互通,且结点之间

的消息传递有时延,相连结点的时延均为一个时间单位。

现给定网络结点的连接关系 link[i]={u,v},其中 u 和 v 表示网络结点。

当指定一个结点向其他结点进行广播,所有被广播结点收到消息后都会在原路径上回复一条

响应消息,请计算发送结点至少需要等待几个时间单位才能收到所有被广播结点的响应消息。

注:

1、N 的取值范围为[1,100];

2、连接关系 link 的长度不超过 3000,且 1 <= u,v <= N;

3、网络中任意结点间均是可达的;

输入描述:

输入的第一行为两个正整数,分别表示网络结点的个数 N,以及时延列表的长度 I;

接下来的 I 行输入,表示结点间的连接关系列表;

最后一行的输入为一个正整数,表示指定的广播结点序号;

输出描述:

输出一个整数,表示发送结点接收到所有响应消息至少需要等待的时长。

示例 1

输入:

5 7

2 1

1 4

2 4

2 3

3 4

3 5

4 5

2

输出:

4

说明:

2 到 5 的最小时延是 2 个时间单位,而 2 到其他结点的最小时延是 1 个时间单位,所以 2

收到所有结点的最大响应时间为 2*2=4。

c 复制代码
#include "stdio.h" 
#include "stdlib.h"
#include "string.h" 
#define MAXNUM 101

int connect[MAXNUM][MAXNUM], mindelay[MAXNUM], used[MAXNUM];

void init(int m)
{
	for (int i = 1; i <= m; i++)
	{
		used[i] = 1;
		mindelay[i] = 9999;
		for (int j = 1; j <= m; j++)
		{
			connect[i][j] = 0;
		}
	}
}

void search(int m)
{
	int i,j;
	for(i = 1; i <= m; i++)
	{
		if((mindelay[i] <= 3000)&&(used[i]))
		{
			for(j = 1; j <= m; j++)
			{
				if(connect[i][j])
				{
					if(mindelay[j] > mindelay[i] + 1)
						mindelay[j] = mindelay[i] + 1;
						connect[i][j] = 0;
				}
			}
			used[i] = 0;
		}
	}
}

int look(int m)
{
	for(int i = 1; i <= m; i++)
	{
		if(used[i])//(mindelay[i] > 3000)
			return 1;
	}
	return 0;
}

int getmax(int m)
{
	int max = 0;
	for(int i = 1; i <= m; i++)
	{
		if(mindelay[i] > max)
			max = mindelay[i];
	}
	return max;
}

int main() 
{
	int n, m, a, b, i;
	while (scanf("%d %d", &m, &n) != EOF)
	{	
		init(m);
		for (i = 0; i < n; i++)
		{
			scanf("%d %d", &a, &b);
			connect[a][b] = 1;
			connect[b][a] = 1;
		}
		scanf("%d", &a);
		mindelay[a] = 0;
		do{
			search(m);
		}while(look(m));
		printf("%d",2*getmax(m));
	}
	return 0;
}

22、题目描述:

DVD 机在视频输出时,为了保护电视显像管,在待机状态会显示"屏保动画",如下图所示,

DVD Logo 在屏幕内来回运动,碰到边缘会反弹:

请根据如下要求,实现屏保 Logo 坐标的计算算法。

1、屏幕是一个 800600 像素的矩形,规定屏幕的左上角点坐标原点,沿横边向右方向
为 X 轴,沿竖边向下方向为 Y 轴;
2、Logo 是一个 50
25 像素的矩形,初始状态下,左上角点坐标记做(x,y),它在 X

和 Y 方向上均以 1 像素/秒的速度开始运动;

3、遇到屏幕四个边缘后,会发生镜面反弹,即以 45°碰撞边缘,再改变方向以 45°弹出;

4、当 Logo 和四个角碰撞时,两个边缘同时反弹的效果是 Logo 会原路返回。

请编码实现,t 秒后 Logo 左上角点的坐标。

输入描述:

输入 3 个数字,以空格分隔:

x y t

第一个数字表示 Logo 左上角点的初始 X 坐标;

第二个数字表示 Logo 左上角点的初始 Y 坐标;

第三个数字表示时间 t,题目要求即求 t 秒后 Logo 左上角点的位置。

输出描述:

输出 2 个数字,以空格分隔:

x y

第一个数字表示 t 秒后,Logo 左上角点的 X 坐标

第二个数字表示 t 秒后,Logo 左上角点的 Y 坐标

补充说明:

所有用例均保证:

1、输入的 x 和 y 坐标会保证整个 Logo 都在屏幕范围内,Logo 不会出画;

2、所有输入数据都是合法的数值,且不会出现负数;

3、t 的最大值为 100000。

示例 1

输入:

0 0 10

输出:

10 10

说明:

输入样例表示 Logo 初始位置在屏幕的左上角点,10s 后,Logo 在 X 和 Y 方向都移动了

10 像素,因此输出 10 10。

示例 2

输入:

500 570 10

输出:

510 570

说明:

输入样例表示初始状态下,Logo 的下边缘再有 5 像素就碰到屏幕下边缘了,5s 后,会与

屏幕碰撞,碰撞后,斜向 45°弹出,又经过 5s 后,Logo 与起始位置相比,水平移动了 10

像素,垂直方向回到了原来的高度。

c 复制代码
#include <stdio.h>

int main()
{
	int x, y, t;
	int xd = 1;
	int yd = 1;
	int xt, yt;
	scanf("%d %d %d", &x, &y, &t);
	while (t)
	{
		if (xd == -1)
		{
			xt = x;
		}
		else
		{
			xt = 800 - x - 50;
		}
		if (yd == -1)
		{
			yt = y;
		}
		else
		{
			yt = 600 - y - 25;
		}
		if (t <= xt && t <= yt)
		{
			x += xd * t;
			y += yd * t;
			t = 0;
		}
		else if (xt < yt)
		{
			x += xd * xt;
			y += yd * xt;
			xd = -xd;
			t -= xt;
		}
		else if (xt > yt)
		{
			x += xd * yt;
			y += yd * yt;
			yd = -yd;
			t -= yt;
		}
		else
		{
			x += xd * xt;
			y += yd * yt;
			xd = -xd;
			yd = -yd;
			t -= xt;
		}
	}
	printf("%d %d", x, y);
	return 0;
}

23、题目描述:

在一条笔直的公路上安装了 N 个路灯,从位置 0 开始安装,路灯之间间距固定为 100 米。

每个路灯都有自己的照明半径,请计算第一个路灯和最后一个路灯之间,无法照明的区间的

长度和。

输入描述:

第一行为一个数 N,表示路灯个数,1<=N<=100000

第二行为 N 个空格分隔的数,表示路径的照明半径,1<=照明半径<=100000*100

输出描述:

第一个路灯和最后一个路灯之间,无法照明的区间的长度和

补充说明:

示例 1

输入:

2

50 50

输出:

0

说明:

路灯 1 覆盖 0-50,路灯 2 覆盖 50-100,路灯 1 和路灯 2 之间(0 米-100 米)无未覆盖的区间

示例 2

输入:

4

50 70 20 70

输出:

20

说明:

[170,180],[220,230],两个未覆盖的区间,总里程为 20

c 复制代码
#include<stdio.h>
#include<math.h>
#include<string.h>

int main()
{
	int N;
	scanf("%d",&N);
	int a[100000];
	for(int i=0;i<N;i++)
	{	
		scanf("%d",&a[i]);
	}
	/*
	for(int i=0;i<N;i++)
	{
		printf("%d ",a[i]);
	}*/
	
	int b[100000];
	memset(b,0,sizeof(b));
	b[0]=a[0];
	int s=0;
	for(int i=1;i<N;i++)
	{
		if(a[i]/100>0)
		{
			s=a[i]/100;
			//printf("i=%d\ns=%d\n",i,s);
			// if(i-s>=0&&i+s<N)
				{
					for(int j=i-s+1;j<=i+s;j++)
					{
						if(j>=0&&j<N)
						{
							b[j]=100;
						}
					}
				if(a[i]%100>a[i-s])
				{
					b[i-s]=fmax(b[i-s],fmin(a[i-s-1]+a[i]%100,100));
				}
				if(a[i]%100>a[i+s])
				{
					a[i+s]=a[i]%100;
				}
			}	
		}
		if(a[i]+a[i-1]<100)
		{
			b[i]=fmax(b[i],a[i]+a[i-1]);
		}
		else
		{
			b[i]=100;
		}
	}
	for(int i=0;i<N;i++)
	{
		//printf("b[%d]=%d\n",i,b[i]);
	}
	int sum=0;
	for(int i=1;i<N;i++)
	{
		sum=sum+b[i];
	}
	printf("%d\n",100*(N-1)-sum);
	return 0;
}

24、C-周末爬山-周末小明准备去爬山锻炼

题目描述:

周末小明准备去爬山锻炼,0 代表平地,山的高度使用 1 到 9 来表示,小明每次爬山或下山高度只能相差 k 及 k 以内,每次只能上下左

右一个方向上移动一格,小明从左上角(0,0)位置出发

输入描述:

第一行输入 m n k(空格分隔),代表 m*n 的二维山地图,k 为小明每次爬山或下山高度差的最大值。然后接下来输入山地图,一共 m 行 n 列,均以空格分隔。

取值范围:0 < m <= 500, 0 < n <= 500, 0< k < 5

输出描述:

请问小明能爬到的最高峰多高,到该最高峰的最短步数,输出以空格分隔。同高度的山峰输出较短步数。如果没有可以爬的山峰则高度

和步数都返回 0。

补充说明:

所有用例输入均为正确格式,且在取值范围内,考生不需要考虑不合法的输入格式。

c 复制代码
#include <stdio.h>

int max = 0;
int m, n, k;
int step = 0;
int max_height = 0;
int arr[500][500];
void calc(int a, int b, int last, int depth);

void dfs(int a, int b, int last, int depth) 
{
	if (a < 0 || b < 0 || a >= m || b >= n ||arr[a][b] == -1 || last + k < arr[a][b] || max_height == max && depth > step) 
	{
		return;
	}
	depth++;
	if (max_height < arr[a][b]) 
	{
		max_height = arr[a][b];
		step = depth;
	}
	if (max_height == arr[a][b] && depth < step) 
	{
		step = depth;
	}
	calc(a, b, arr[a][b], depth);
}

void calc(int a, int b, int last, int depth) 
{
	int t = arr[a][b];
	arr[a][b] = -1;
	dfs(a, b + 1, last, depth);
	dfs(a, b - 1, last, depth);
	dfs(a + 1, b, last, depth);
	dfs(a - 1, b, last, depth);
	arr[a][b] = t;
}

int main() 
{
	scanf("%d%d%d", &m, &n, &k);
	for (int i = 0; i < m; ++i) 
	{
		for (int j = 0; j < n; ++j) 
		{
			scanf("%d", &arr[i][j]);
			max = max > arr[i][j] ? max : arr[i][j];
		}
	}
	calc(0, 0, arr[0][0], 0);
	printf("%d %d\n", max_height, step);
	return 0;
}

25、C-最远足迹-某探险队负责对地下洞穴进行探险

题目描述:

某探险队负责对地下洞穴进行探险。探险队成员在进行探险任务时,随身携带的记录器会不定期地记录自身的坐标,但在记录的间隙中

也会记录其他数据。探索工作结束后,探险队需要获取到某成员在探险过程中相对于探险队总部的最远的足迹位置。

  1. 仪器记录坐标时,坐标的数据格式为(x,y),如(1,2)、(100,200),其中 0<x<1000,0<y<1000。同时存在非法坐标,如(01,1)、
    (1,01),(0,100)属于非法坐标。
  2. 设定探险队总部的坐标为(0,0),某位置相对总部的距离为:xx+yy。
  3. 若两个座标的相对总部的距离相同,则第一次到达的坐标为最远的足迹。
  4. 若记录仪中的坐标都不合法,输出总部坐标(0,0)。
    备注:不需要考虑双层括号嵌套的情况,比如 sfsdfsd((1,2))。
    输入描述:
    字符串,表示记录仪中的数据。
    如:ferga13fdsf3(100,200)f2r3rfasf(300,400)
    输出描述:
    字符串,表示最远足迹到达的坐标。
    如: (300,400)
    补充说明:
c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
	char s[1000] = {0};
	gets(s);
	int maxVal = 0, x = 0, y = 0;
	char * pos = s;
	while(pos = strchr(pos, '('))
	{
		++pos;
		if(pos[0] == '0' || strchr(pos, ',')[1] == '0')
		{
			pos++;
			continue;
		}
		int a = 0;
		int b = 0;
		sscanf(pos, "%d,%d", &a, &b);
		if(a <= 0 || a >= 1000 || b <= 0 || b >= 1000)
		{
			continue;
		}
		if(maxVal < a * a + b * b)
		{
			maxVal = a * a + b * b;
			x = a;
			y = b;
		}
	}
	printf("(%d,%d)\n", x, y);
	return 0;
}
相关推荐
好开心3329 分钟前
axios的使用
开发语言·前端·javascript·前端框架·html
又蓝1 小时前
使用 Python 操作 Excel 表格
开发语言·python·excel
余~~185381628001 小时前
稳定的碰一碰发视频、碰一碰矩阵源码技术开发,支持OEM
开发语言·人工智能·python·音视频
刚学HTML2 小时前
leetcode 05 回文字符串
算法·leetcode
Am心若依旧4092 小时前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
明月看潮生2 小时前
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
开发语言·青少年编程·单元测试·编程与数学·goweb
大G哥2 小时前
java提高正则处理效率
java·开发语言
stm 学习ing2 小时前
HDLBits训练5
c语言·fpga开发·fpga·eda·hdlbits·pld·hdl语言
AC使者2 小时前
#B1630. 数字走向4
算法
冠位观测者2 小时前
【Leetcode 每日一题】2545. 根据第 K 场考试的分数排序
数据结构·算法·leetcode