前言:C语言萌新第一次写博客,如有不正确和需要改进的地方,还请各位大佬不吝赐教。
移动应用开发实验室二面题解
1.求最短时间
题目详情:
思路:
由题意可得,当甲乙两人同时到达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
思路:
本题使用到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句子反转
题目详情:
思路:
由题,我们可以直接从后往前倒数处理和输出句子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.明明的随机数
题目详情:
思路:
首先,题目要求去重和排序。
在排序上,我们可以利用数组本身具有的有序性来实现,因为随机数范围为[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.队列安排
题目详情:
思路:
由题,我们可以采用数组模拟双向链表,我们将一号位固定,从二号位开始插入学生,通过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总部
题目详情:
!本题需要使用到深度优先搜索🔍,我是菜狗,不太会深搜,烦请各位大佬赐教!
(待我学成归来 一定补上该题的题解)
7.小A的糖果
题目详情:
思路:
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