算法题小总结(2)

难度对我来说有点提高

1.学生成绩查找系统

学生成绩查找系统是一个根据姓名查找学生成绩的系统。系统可以录入是学生的姓名和成绩,录完之后可以输入查找条件,即学生的姓名,查找该生的成绩,如果存在该生的信息,则输出该生成绩,否则给出查无此人的提示信息。

输入:题目输入包括录入学生信息和输入查找条件以及输入结束标志。insert语句表示录入学生信息,格式为字符insert+空格+字符串+空格+数字+换行符 ,例如 insert xiaohua 99 ,表示录入姓名为xiaohua的学生,其成绩为99 。 find语句表示查找某学生的信息,格式为字符find+空格+字符串+换行符。例如 find xiaohua。end语句表示输入结束,格式为字符end

输出:对应每一条find语句都应该有一条输出语句。对于find xiaohua这条输入语句,因为已经插入过xiaohua的成绩 需要输出 99+换行符,否则查找不到输出-1+换行符。

Sample 1

InputcopyOutputcopy
insert zhangsan 90
insert lisi 78
insert xiaoming 86
find xiaoming
find Jack
end
86
-1

思路

使用结构体存储,strcmp比较,这个题还是简单的

代码展示

#include<stdio.h>
#include<string.h>

struct student{
	int n;
	char m[128];
}a[10006];

int main()
{
	char b[128];
	int i=0;
	while(scanf("%s",b))
	{
		int x=0;
		if(strcmp(b,"end")==0){
			break;
		}else if(strcmp(b,"insert")==0){
			scanf("%s %d",&a[i].m,&a[i].n);
			i++;
		}else if(strcmp(b,"find")==0){
			char c[128];
			scanf("%s",c);
			x=0;
			for(int j=0;j<i;j++){
				if(strcmp(a[j].m,c)==0){
					printf("%d\n",a[j].n);
					x+=1;
					break;
				}
			}
			if(x==0){
				printf("-1\n");
			}
		}
	}
	return 0;
}

 2.小孩报数问题

/*有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,
报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,
如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),
求小孩出列的顺序。
Input

第一行输入小孩的人数N(N<=64) 
接下来每行输入一个小孩的名字(人名不超过15个字符) 
最后一行输入W,S (W < N),用逗号","间隔
Output

按人名输出小孩按顺序出列的顺序,每行输出一个人名
Sample Input

5
Xiaoming
Xiaohua
Xiaowang
Zhangsan
Lisi
2,3
Sample Output

Zhangsan
Xiaohua
Xiaoming
Xiaowang
Lisi*/
 

思路

使用结构体或二维数组来存储,两层循环,外层控制次数,内层找名字

代码展示

#include<stdio.h>

struct children{
	int count;
	char name[15];
}a[65];
int main()
{
	int n,w,s;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	    scanf("%s",a[i].name);
	scanf("%d,%d",&w,&s);
	int k=w-2;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<s;j++)
		{
			k++;
			if(k>=n) k%=n;
			if(a[k].count==1)//判断是否提取过 
			{
				j--;
				continue;
			}else continue;
		}
		printf("%s\n",a[k].name);
		a[k].count=1;
	}
	return 0;
}

3.wguran 

 

 思路

首先没有删除操作,如果ai不能改变,那么就只能改变i,即在ai之前插入数,由于要求最少,那么肯定插入的是ai与i插值的个数

代码展示

#include<stdio.h>

int main()
{
	int t,n,a[105];
	scanf("%d",&t);
	while(t--)
	{
		int ret=0;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		    scanf("%d",&a[i]);
		for(int i=1;i<=n;i++)
		{
			if(a[i]>i+ret) ret+=a[i]-(i+ret);
		}
		printf("%d\n",ret);
	}
	return 0;
}

 4.轻重搭配

/*n 个同学去动物园参观,原本每人都需要买一张门票,
但售票处推出了一个优惠活动,一个体重为 x 的人可以和体重至少为 2x 配对,
这样两人只需买一张票。现在给出了n人的体重,请你计算他们最少需要买几张门票?

输入格式
第一行一个整数 n,表示人数。

第二行 n 个整数,每个整数a表示每个人的体重。

输出格式
一个整数,表示最少需要购买的门票数目。
1 和 9 配对,7 和 3 配对,剩下 5,5 单独,一共买四张票。*/

思路

先排序,然后分为两段,将第一个与第二段中最瘦的匹配,以此类推

这里我使用了sort函数

代码展示

#include<stdio.h>
#include<algorithm>
using namespace std;

int main()
{
	int n,a[500000],i=0,c,e;
	scanf("%d",&n);
	for(;i<n;i++) scanf("%d",&a[i]);
	sort(a,a+n);
	c=n/2;e=n;
	for(i=0;i<n/2;i++)
	{
		while(2*a[i]>a[c]&&c<n) c++;
		if (c>=n) break;
		e--;
		c++;
	}
	printf("%d\n",e);
} 

5.两个子序列

/*学习了字符串相关知识的王大队长在思考一些问题:现在王大队长有一个字符串 s ,
他想找到两个非空字符串 a and b ,来满足下面的条件:

字符串 a 和 b 都是 s 的子序列;
对于每个索引 i, 字符串 s 的字符必须恰好属于字符串 a或 b 其中一个;
字符串 a 必须是字典序 最小的,字符串 b 则可以是任何可能的字符串;
现在给定字符串 s, 请打印出任意一组有效的 a 和 b.

Input
每个测试包含多个测试用例。第一行包含测试用例的数量 t (1≤t≤1000). 测试用例的描述如下:

每个测试用例的第一行也是唯一一行包含一个字符串 s (2≤∣s∣≤100 其中 |s| 表示 s 的长度). 字符串 s 由小写拉丁字母组成。

Output
对于每个测试用例,打印满足给定条件的字符串 a 和 b ,如果有多个答案,请输出任意一个。*/

 思路

找出字典序最小的,然后从这里分开,再使用两个循环,打印之前和之后的部分即可

代码展示

#include<stdio.h>
#include<string.h>

int main()
{
	int n,f=0;
	char a[101];
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		char min='z'+1;
		scanf("%s",a);
		for(int j=0;j<strlen(a);j++)
		{
			if(a[i]<min)
			{
				min=a[i];
				f=i;
			}
		}
		printf("%c ",min);
		for(int j=0;j<f;j++)
		    printf("%c",a[j]); 
		for(int j=f+1;j<strlen(a);j++)
		    printf("%c",a[j]);
		printf("\n");
	}
	return 0;
}

 6.纪念品分组

元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。

输入描述:
第 1 行包括一个整数 w,为每组纪念品价格之和的上限。
第 2 行为一个整数n,表示购来的纪念品的总件数。
第 3 ~ n+2 行每行包含一个正整数 pi ( 5 ≤ pi ≤ w ) ,表示所对应纪念品的价格。

输出描述:
包含一个整数,即最少的分组数目。

InputcopyOutputcopy
100
9
90
20
20
30
50
60
70
80
90
6

思路

先排序,然后从两端开始配对。如果能配上一对,则记录并移动两端指针,否则贵重纪念品单独一组并只移动一端指针。

代码展示

w=int(input())
n=int(input())
l=[int(input()) for i in range(n)]
l.sort()
u=n
n1,n2=0,n-1
while n2>n1:
    if l[n1]+l[n2]>w:
        n2-=1
    else:
        u-=1
        n1+=1
        n2-=1
print(u)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值