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

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

第一题:小车问题

题目描述

       甲、乙两人同时从 A 地出发要尽快同时赶到 B 地。出发时 A 地有一辆小车,可是这辆小车除了驾驶员外只能带一人。已知甲、乙两人的步行速度一样,且小于车的速度。问:怎样利用小车才能使两人尽快同时到达。

输入格式:

仅一行,三个实数,分别表示 AB 两地的距离 s,人的步行速度 a,车的速度 b。

输出格式:

两人同时到达 B 地需要的最短时间,保留 66 位小数。

sample 1

Input

output

120 5 259.600000
题解:

这道题可以根据甲乙两人同时到达终点列方程,驾驶员带一个行驶一段距离x之后返回去接正在行走的另一个人,碰到之后前往终点,甲乙两人同时到达。即t=x/b+(s-x)/a,(s-x)/a=2*(2*x/(a+b)-x/b)+(s-x)/b,化简得x=(b+a)*s/(b+3*a)。

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

 第二题: 笨小猴

题目描述:

笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!

这种方法的具体描述如下:假设 maxn是单词中出现次数最多的字母的出现次数,minn 是单词中出现次数最少的字母的出现次数,如果 maxn−minn 是一个质数,那么笨小猴就认为这是个 Lucky Word,这样的单词很可能就是正确的答案。

输入格式:

一个单词,其中只可能出现小写字母,并且长度小于 100。

输出格式:

共两行,第一行是一个字符串,假设输入的的单词是 Lucky Word,那么输出 Lucky Word,否则输

出 No Answer

第二行是一个整数,如果输入单词是 Lucky Word,输出 maxn−minn的值,否则输出 0。

sample1

Input

Output

error

Lucky Word

2

sample 2

Input

Output

olympic

No Answer

0

题解:

打印出100以内的所有质数用遍历字符串数组,用新的数组记录字母出现的次数,遍历字母,比较并找出新的数组的最大最小值,相减,再遍历打印出来的质数,若是质数,则输出Lucky Word及质数,否则输出No Answer和0。

#include<stdio.h>
#include<string.h>
int main() {
	char s[100] = { 0 };
	int sum[100] = { 0 };
	int max = 0, min = 100;
	int prime[25] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97 };
	scanf("%s", s);
	int n = strlen(s);
	for (int i = 0; i < n; i++) {
		sum[s[i] - 'a']++;
	}
	for (int i = 0; i < 100; i++) {
		if (sum[i] > max) {
			max = sum[i];
		} else if (sum[i] > 0 && sum[i] < min) {
			min = sum[i];
		}
	}
	for (int i = 0; i < 25; i++) {
		if (max - min == prime[i]) {
			printf("Lucky Word\n%d", max - min);
			return 0;
		}
	}
	printf("No Answer\n0");
	return 0;
}

第三题:拯救oibh总部

 题目背景:

oibh 总部突然被水淹没了!现在需要你的救援……

题目描述:

oibh 被突来的洪水淹没了,还好 oibh 总部有在某些重要的地方起一些围墙。用 * 号表示,而一个四面被围墙围住的区域洪水是进不去的。

oibh 总部内部也有许多重要区域,每个重要区域在图中用一个 0 表示。

现在给出 oibh 的围墙建设图,问有多少个没被洪水淹到的重要区域。

输入格式:

第一行为两个正整数 x,y。

接下来 x 行,每行 y 个整数,由 * 和 0 组成,表示 oibh 总部的建设图。

输出格式:

输出没被水淹没的 oibh 总部的 0 的数量。

sample 1

Input

Output

4 5
00000
00*00
0*0*0
00*00
1

sample 2

Input

Output

5 5
*****
*0*0*
**0**
*0*0*
*****
5
 题解:

这道题是深度优先搜索,DFS被用来标记所有被淹没的格子,用search函数,对当前格子的位置的相邻上下左右进行搜索遍历,如果相邻的格子未被洪水淹没,递归调用search函数进行处理。最外层如果是空,则洪水一直向里走,从最外层开始,搜第一列和最后一列格子,在搜索第一行和最后一行格子,最后再搜空的格子,输出空格子数。

#include<stdio.h>
int n, m, s = 0;
int kx[5] = { 0,1,-1,0,0 };
int ky[5] = { 0,0,0,1,-1 };
int a[501][501];
void search(int x, int y) {
    a[x][y] = 1;//先标记被淹没了 
    for (int i = 1; i <= 4; i++) {//搜索 
        int x0 = x + kx[i];
        int y0 = y + ky[i];
        if (x0 > 0 && x0 <= n && y0 > 0 && y0 <= m && a[x0][y0] == 0)search(x0, y0);
    }
}
int main() {
    scanf("%d%d", &n, &m);
    char e;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf(" %c", &e);
            if (e == '*') {
                a[i][j] = 1;//如果是障碍就输入1
            } else {
                a[i][j] = 0;//可以过就是0 
            }
        }
    }
    for (int i = 1; i <= n; i++) {//搜索第一列和最后一列
        if (a[i][1] == 0) search(i, 1);//如果有能过的就搜索 
        if (a[i][m] == 0) search(i, m);
    }
    for (int i = 1; i <= m; i++) {//搜索第一行和最后一行的格子 
        if (a[1][i] == 0) search(1, i);
        if (a[n][i] == 0) search(n, i);
    }
    for (int i = 1; i <= n; i++) {//最后搜索没有被淹的格子 
        for (int j = 1; j <= m; j++) {
            if (a[i][j] == 0) {
                s++;
            }
        }
    }
    printf("%d", s);
    return 0;
}

第四题:对列安排

题目描述:

一个学校里老师要将班上 N 个同学排成一列,同学被编号为 1∼N,他采取如下的方法:

  1. 先将 1 号同学安排进队列,这时队列中只有他一个人;

  2. 2∼N 号同学依次入列,编号为 i 的同学入列方式为:老师指定编号为 i 的同学站在编号为 1∼(i−1) 中某位同学(即之前已经入列的同学)的左边或右边;

  3. 从队列中去掉 M 个同学,其他同学位置顺序不变。

在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。

输入格式:

第一行一个整数 N,表示了有 N 个同学。

第 2∼N 行,第 i 行包含两个整数 k,p,其中 k为小于 i 的正整数,p 为 0或者 1。若 p 为 0,则表示将 i 号同学插入到 k 号同学的左边,p 为 1 则表示插入到右边。

第N+1 行为一个整数 M,表示去掉的同学数目。

接下来 M 行,每行一个正整数 x,表示将 x 号同学从队列中移去,如果 x 号同学已经不在队列中则忽略这一条指令。

输出格式:

一行,包含最多N 个空格隔开的整数,表示了队列从左到右所有同学的编号。

 sample 1

Input

Output

4
1 0
2 1
1 0
2
3
3
2 4 1
题解:

这道题我的思路是用数组模拟双向链表,定义一个学生结构体,如果输入的p的值是1则将当前节点插入节点k右边,否则插入左边。通过m的值表示要删除的节点数量,用循环读取要删除节点的编号,并将对应节点的id置1,表示需要被删除。注意初始化,我们可以定义第0个学生,从第0个学生的右手牵起,再到0结束。最后,用循环遍历链表,输出未被删除的节点编号。

#include<stdio.h>
int n, m;
struct Stdent {
	int l, r;
	int id;
}s[1000005];

int main() {
	scanf("%d", &n);
	for (int i = 2; i <= n; i++) {
		int k, p;
		scanf("%d%d ", &k, &p);
		if (p == 1) {
			s[i].r = s[k].r;
			s[i].l = k;
			s[s[k].r].l = i;
			s[k].r = i;
		} else {
			s[i].l = s[k].l;
			s[i].r = k;
			s[s[k].l].r = i;
			s[k].l = i;
		}
	}
	scanf("%d", &m);
	for (int i = 1; i <= m; i++) {
		int x;
		scanf("%d", &x);
		s[x].id = 1;//标记要删除的人
	}
	int now;
	for (int i = 1; i <= n; i++) {
		if (s[i].l == 0 && s[i].id != 1) {
			now = i;
		}
	}
	while (now) {
		if (s[now].id == 0) {
			printf("%d ", now);
		}
		now = s[now].r;
	}
	return 0;
}

第五题:句子反转

题目描述:

给定一行句子,每个词之间用空格隔开,要么是全小写英文单词,要么是全大写英文单词,要么是自然数。

要求将这些单词倒序输出。而且对于每个单词,如果是小写词,应当转为大写;如果是大写词,应当转为小写;如果是自然数,应该倒转输出。

举一个例子:

we choose TO go 2 the 123 moon

程序应当输出:

MOON 321 THE 2 GO to CHOOSE WE
输入格式:

仅一行,即需要反转的句子。

输出格式:

仅一行,表示程序对句子的处理结果。

Input

Output

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

这道题主要考察字符串的大小写转化,字符串整体上逆置,先判断是否是字母,是就大小写转换,并逐个输出,若第一个字符是数字,则逆序输出,若不是数字,直接输出该单词,当不是最后一个单词时,在后面添加空格。

#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;
	}
}

第六题:明明的随机数

题目描述:

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数 (N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

输入格式:

输入有两行,第1行为1正整数,表示所生成的随机数的个数N。

第2行有N个用空格隔开的正整数,为所产生的随机数。

输出格式:

输出也是两行,第1行为1个正整数 M,表示不相同的随机数的个数。

第2行为M个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

sample 1

Input

Output

10
20 40 32 67 40 20 89 300 400 15
8
15 20 32 40 67 89 300 400
 题解:

这道题的整体思路是先进行排序,再去充,采用冒泡排序按照从小到大排序,之后开辟一个新的数组用来存储不相同的元素再输出,用count来记录不相同元素的个数再输出。

#include<stdio.h>
void sort(int* arr, int n) {
	int i = 0;
	for (i = 0; i < n - 1; i++) {
		for (int j = 0; j < n - 1 - i; j++) {
			if (arr[j] > arr[j + 1]) {
				int p = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = p;
			}
		}
	}
}

int main() {
	int n, arr[100] = { 0 };
	int i = 0, j = 0;
	int count = 1;
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		scanf("%d", &arr[i]);
	}
	sort(arr, n);
	int s[100];
	s[0] = arr[0];
	for (j = 1; j < n; j++) {
		if (arr[j] == arr[j - 1])
		    continue;
	    else 
			s[count++] = arr[j];
	}
	printf("%d\n", count);
	for (int i = 0; i < count; i++) {
		printf("%d ", s[i]);
	}
	return 0;
}

第七题:小A的糖果

 题目描述:

小 A 有 n 个糖果盒,第 i 个盒中有 ai​ 颗糖果。

小 A 每次可以从其中一盒糖果中吃掉一颗,他想知道,要让任意两个相邻的盒子中糖的个数之和都不大于 x,至少得吃掉几颗糖。

输入格式:

输入的第一行是两个用空格隔开的整数,代表糖果盒的个数 n 和给定的参数 x。

第二行有 n 个用空格隔开的整数,第 i 个整数代表第 i 盒糖的糖果个数 ai​。

输出格式:

输出一行一个整数,代表最少要吃掉的糖果的数量。

sample

Input

Output

3 3
2 2 2
1
6 1
1 6 1 2 0 4
11
5 9
3 1 4 1 5
0
题解:

这道题考察贪心算法,局部最优达到整体最优解,遍历数组,如果相邻元素之和大于x,一次要吃掉最少的糖果,即元素之和减去x之后,后一个糖果数为x减去前一个盒子的糖果数。

#include<stdio.h>
int main() {
	long long  sum = 0;
	int arr[100005];
	int n, x;
	scanf("%d%d ", &n, &x);
	for (int i = 1; i <= n; i++) {
		scanf("%d ", &arr[i]);
	}
	for (int i = 0; i < n; i++) {
		if (arr[i] + arr[i + 1] > x) {
			sum = sum + arr[i] + arr[i + 1] - x;
			arr[i + 1] = x - arr[i];
		}
	}
	printf("%lld", sum);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值