2024上半年移动应用开发实验室二面题解

前言:C语言萌新第一次写博客,如有不正确和需要改进的地方,还请各位大佬不吝赐教。

移动应用开发实验室二面题解

1.求最短时间 

题目详情:

fe36d41ee6c5408b8ec420a8613bc6d7.png

思路:

由题意可得,当甲乙两人同时到达B地,此时两人从A地到B地距离为s所用的时间最短。

由此,有如下想法。

小车先载着甲行驶一段距离x,在此过程中,乙也在步行前进。

随后在某一合适时间节点将甲放在半途,折回去接走在半路的乙,两者相向而行,中途相遇,小车将乙载回终点,此时甲也恰好步行至终点。

由此,我们应该以后半段,甲步行时间与乙坐车时间相等为突破口。列出以下等式:

(s-x)/a=2*(2*x/(a+b)-x/b)+(s-x)/b

化简后:x=(b+a)*s/(b+3*a)

最后时间 (t甲=t乙,此处以t甲列式):

x/b+(s-x)/a

代码实现:

#include <stdio.h>
int main() {
	double s, a, b, x;
	double t;
	scanf("%lf %lf %lf", &s, &a, &b);
	x = (b + a) * s / (b + 3 * a);
	t = x / b + (s - x) / a;
	printf("%.6lf", t);
	return 0;
}

 运行结果:

120 5 25
9.600000

2.笨小猴的Lucky Word  

27f50910b1064a7989b5ea80d0f77fe5.png

 思路:

本题使用到bool类型函数判断素数和for循环遍历单词中的每个字母并进行对比。

1.读入单词并用for循环进行遍历,设置计数数组长度为26个字母的长度,每读到一个字母,将其减去a的ASCLL值(题目说明单词内均为小写字母)并作为计数数组的下标,让对应位置数组元素加1,实现相同字母计数。

2.设置最大值最小值分别为100和0,并将其与计数数组中的每个元素进行比较。若有更大或更小数,则进行替换。

3.用最大值减去最小之后,进行素数判断。

4.分类输出不同结果。

代码实现:

#include<stdio.h>
#include<stdbool.h>

bool SSPD(int n) {
	if (n == 1 || n == 0) {
		return false;
	}
	for (int i = 2; i < n; i++) {
		if (n % i == 0) {
			return false;
		}
	}
	return true;
}

int main() {
	char word[100];
	int count[26] = {0};
	int maxn = 0, minn = 100;
	scanf("%s",&word);
	for (int i = 0; word[i] != '\0'; i++) {
		count[word[i] - 'a']++;
	}
	for (int i = 0; i < 26; i++) {
		if (count[i] >= maxn) {
			maxn = count[i];
		}
		if (count[i] <= minn && count[i] > 0) {
			minn = count[i];
		}
	}
	if (SSPD(maxn - minn)) {
		printf("Lucky Word\n");
		printf("%d",maxn - minn);
	} else {
		printf("No Answer\n");
		printf("0");
	}
	return 0;
}

 运行结果:

error
Lucky Word
2
olympic
No Answer
0

3.T3句子反转 

题目详情:

e2949a85f0e24773b6b25e7de6302255.png

 思路:

由题,我们可以直接从后往前倒数处理和输出句子for循环倒序输出,声明并初始化两个变量m和n,并使它们都指向句子最后一个字符,以便我们倒数处理句子。

输出时用if-else进行分类,即当遇到数字时直接输出;当遇到字母时,若其ASCLL值在['A','Z'],则减去'A'加上'a',转化成相应的小写字母并输出,在['a','z']则减去'a'加上'A',转化为相应大写字母并输出(同时要注意将m>0和m=0的情况进行分类讨论,当m=0时,即已经处理到句子的第一个单词)。

在每次对单词处理完输出后,若m>0,则要输出一个空格;若m=0,则已经处理到句子的第一个单词,无需输入空格。

代码实现:

#include <stdio.h>
#include <string.h>
int main() {
	char ch[6010];
	int m, n, i;
	gets(ch);//读取输入的一整行句子
	m = strlen(ch) - 1;
	n = strlen(ch) - 1;  //使m,n指向最后一个字符
	while (m > 0) {    //该循环用于处理句子中的每个单词
		while (m > 0 && ch[m] != ' ') {
			m--;    //此时m指向空格 以空格为界限 分别处理每个单词
		}
		if (ch[m + 1] <= 'Z' && ch[m + 1] >= 'A' || ch[m + 1] <= 'z' && ch[m + 1] >= 'a') {  //根据字符类型分类
			if (m > 0) {  //判断当前字母是否为句子的首字母
				if (ch[m + 1] <= 'Z' && ch[m + 1] >= 'A') {
					for (i = m + 1; i <= n; i++) {
						ch[i] = ch[i] - 'A' + 'a';
						printf("%c", ch[i]);
					}
				}
				else {
					for (i = m + 1; i <= n; i++) {
						ch[i] = ch[i] - 'a' + 'A';
						printf("%c", ch[i]);
					}
				}
			}
			if (m == 0) {  //此时已经处理到句子的第一个单词
				if (ch[m] <= 'Z' && ch[m] >= 'A') {
					for (i = 0; i <= n; i++) {
						ch[i] = ch[i] - 'A' + 'a';
						printf("%c", ch[i]);
					}
				}
				else {
					for (i = 0; i <= n; i++) {
						ch[i] = ch[i] - 'a' + 'A';
						printf("%c", ch[i]);
					}
				}
			}
		}
		else {  //如果当前字符不是字母,则反向直接输出
			if (m > 0) {
				for (i = n; i > m; i--) {
					printf("%c", ch[i]);
				}
			}
			else {
				for (i = n; i >= m; i--) {
					printf("%c", ch[i]);
				}
			}
		}
		if (m > 0) {
			printf(" "); //每次处理完后输出一个空格(除第一个单词外)
		}
		m--;
		n = m;
	}
}

运行结果:

we choose TO go 2 the 123 moon
MOON 321 THE 2 GO to CHOOSE WE

4.明明的随机数

题目详情:155757509aa4482c87b08c58790214f8.png

思路:

首先,题目要求去重和排序。

在排序上,我们可以利用数组本身具有的有序性来实现,因为随机数范围为[1,1000],所以我们声明一个长度为1001的数组,以确保每个数字以数组下标的形式都能被读入,在读入时就完成了排序。

在去重时,我们只需在以数组形式读入数据的for循环中嵌套一个条件语句,即当数组中该位置的值为零时,才将数据读入,并让count++;否则数据不会被读入。

最后,只需输出数组中值不为零的元素即可。

代码实现:

#include <stdio.h>
int main() {
	int N, a[1001] = {0};  //数组长度设置为1001,确保大小在[1,1000]的数都能被存放
	int t;
    int count = 0;
	scanf("%d", &N);
	for (int i = 0; i < N; i++) {
		scanf("%d", &t);  //将数字以数组下标读入,读入的同时便完成了排序
		if (a[t] == 0) {
			a[t] = t;  //如果数组中该位置无数值,则将该数放在该位置;重复则不放置,实现去重
			count++;
		}
	}
	printf("%d\n", count);
	for (i = 0; i < 1001; i++) {
		if (a[i] != 0) {  //将数组中存放有数字的元素输出
			printf("%d ", a[i]);
	    }
    }
	return 0;
}

 运行结果:

10
20 40 32 67 40 20 89 300 400 15
8
15 20 32 40 67 89 300 400
D:\VS项目\MM suijishu\x64\Debug\MM suijishu.exe (进程 1848)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

 

5.队列安排

题目详情:

b1615ae1507b45b5afa12672dda5144f.png

思路:

由题,我们可以采用数组模拟双向链表,我们将一号位固定,从二号位开始插入学生,通过if-else语句分类讨论应该插到第k个人的哪一边,向右插入时,令被插入学生左边是k,右边是原k右边的人即可;向左插入同理。

删除队列中的学生时,我们首先标记要被删除的学生,将其赋值为1,其余学生均为0

代码实现:

#include <stdio.h>
int n, m;
struct node {
	int l, r;
	int id;
} a[1000005] = {0};
int main() {
	scanf("%d", &n);
	for (int i = 2; i <= n; i++) {  //从2开始,将i号学生插到k号的一边 
		int k, p;
		scanf("%d %d", &k, &p);  //第几个人的哪一边 
		if (p == 1) {  //插在右边 
			a[i].r = a[k].r;  //i右边的人是原来k右边的人 
			a[i].l = k;  //i左边的人是k 
			a[a[k].r].l = i;  //原来k右边的人现在左边的人是i 
			a[k].r = i;  //k右边的人是i 
		} else {  //插在左边,l,r对调即可 
			a[i].l = a[k].l;
			a[i].r = k;
			a[a[k].l].r = i;
			a[k].l = i;
		}
	}
	scanf("%d", &m);
	for (int i = 1; i <= m; i++) {
		int x;
		scanf("%d", &x);
		a[x].id = 1;  //标记要删除的人 
	}
	int now;
	for (int i = 1; i <= n; i++) {
		if (a[i].l == 0 && a[i].id != 1) {
			now = i;
		}
	}
	//如果没有赋值自动赋为0 
	//找到整个队列的第一个人 
	//如果左边没人且这个人不会被删,将其赋给now 
	while (now) {//如果now存在的话 
		if (a[now].id == 0) {
			printf("%d ", now);
		}
		now = a[now].r;  //下一个 
	}
	return 0;
}

 运行结果:

4
1 0
2 1
1 0
2
3
3
2 4 1

6.拯救oibh总部

题目详情:

d3540a6cece94ba18dcf90f689fcc74b.png

!本题需要使用到深度优先搜索🔍,我是菜狗,不太会深搜,烦请各位大佬赐教!

(待我学成归来 一定补上该题的题解)

7.小A的糖果

题目详情:

15ce7fc4c2f04b4da971b03dc722da25.png

思路:

1.遍历读取每个糖果盒中的糖果数量 ai,如果糖果盒中的糖果数量是否超过了参数 x,则通过循环减少糖果数量,并记录减少的次数,以确保每个盒子中的糖果数量不超过 x

2.然后,遍历每对相邻的糖果盒,检查它们的糖果数量之和是否超过了参数 x。如果超过了,则从相邻盒子中移除的糖果数量,并将这个数量加到计数器 count 中,同时更新相邻盒子中的糖果数量,确保它们之和不超过 x

3.最后,输出计数器 count 的值,即最少需要吃掉的糖果数量。

代码实现:

#include <stdio.h>

int main() {
    long int a[100000] = {0};
    long int n;
    long int x;
    long int count = 0;
    scanf("%ld %ld", &n, &x);
    for (int i = 0; i < n; i++) {
        scanf("%ld", &a[i]);
        while (a[i] > x) {
            a[i]--;
            count++;
        }
    }
    for (int i = 0; i < n - 1; i++) {
        if ((a[i] + a[i + 1]) > x) {
            count += (a[i] + a[i + 1]) - x;
            a[i + 1] -= (a[i] + a[i + 1]) - x;
        }
    }
    printf("%ld", count);
    return 0;
}

运行结果:

3 3
2 2 2
1
6 1
1 6 1 2 0 4
11
5 9
3 1 4 1 5
0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值