同济大学2022年转专业(软件工程)机试
共3题,每题100分,考试时间3小时。
第一题
题目描述
给定一个字符串\(s\)和一个整数\(k\),从字符串开头算起,每计数至\(2k\)个字符,就反转这\(2k\)字符中的前\(k\)个字符。
如果剩余字符少于\(k\)个,则将剩余字符全部反转。
如果剩余字符小于\(2k\)但大于或等于\(k\)个,则反转前\(k\)个字符,其余字符保持原样。
输入格式
输入为\(1\)行,由一个纯字母组成的字符串和一个非负整数组成,字符串和整数之间用空格分隔开。
输出格式
输出为\(1\)行,只需要输出反转后的字符串即可
样例 #1
样例输入
1abcdefg 2样例输出
1bacdfeg样例 #2
样例输入
1abcd 2样例输出
1bacd
题解
这个问题等价于将字符串s分成\(k\)段,最后不足\(k\)的部分也计为一段,然后以每一段作为下标(从\(0\)开始),第奇数段(即(i+1)%!=0或者(i+1)&1)的字符串进行反转,注意最后不足\(k\)的部分可以通过一个取小函数来实现。
1 | |
第二题
题目描述
毛哥买了一些糖果
candies,打算把它们分给排好队的n = num_people个小朋友。给第一个小朋友\(1\)颗糖果,第二个小朋友\(2\)颗,依此类推,直到给最后一个小朋友\(n\)颗糖果。
然后,我们再回到队伍的起点,给第一个小朋友\(n + 1\)颗糖果,第二个小朋友\(n + 2\)颗,依此类推,直到给最后一个小朋友\(2 * n\)颗糖果。
重复上述过程(每次都比上一次多给出一颗糖果,当到达队伍终点后再次从队伍起点开始),直到我们分完所有的糖果。注意,就算我们手中的剩下糖果数不够(不比前一次发出的糖果多),这些糖果也会全部发给当前的小朋友。
返回一个长度为
num_people、元素之和为candies的数组(我们用ans来表示),以表示糖果的最终分发情况(即ans[i]表示第\(i\)个小朋友分到的糖果数)。输入格式
输入为\(1\)行,两个非负整数糖果数量(
candies) 和 小朋友数量(num_people),他们之间用空格分隔开输出格式
输出为\(1\)行,
num_people个整数,中间用空格分开。每个整数代表小朋友分到的糖果数。样例 #1
样例输入
17 4样例输出
11 2 3 1样例解释
第一次,
ans[0] += 1,数组变为[1,0,0,0]。第二次,
ans[1] += 2,数组变为[1,2,0,0]。第三次,
ans[2] += 3,数组变为[1,2,3,0]。第四次,
ans[3] += 1(因为此时只剩下 1 颗糖果),最终数组变为[1,2,3,1]。样例 #2
样例输入
110 3样例输出
15 2 3样例解释
第一次,
ans[0] += 1,数组变为[1,0,0]。第二次,
ans[1] += 2,数组变为[1,2,0]。第三次,
ans[2] += 3,数组变为[1,2,3]。第四次,
ans[0] += 4,最终数组变为[5,2,3]。数据范围
\(1\) ≤
candies≤ \(10^9\)\(1\) ≤
num_people≤ \(1000\)
题解
依据题意模拟即可
1 | |
第三题
题目描述
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
输入格式
输入为\(n+1\)行
第一行为两个用空格隔开的整数\(n\)和\(m\)
第\(1\) - \(n+1\)行为\(n × m\)矩阵,其中每行有\(m\)个用空格隔开的非负整数。
输出格式
输出为一个整数,即岛屿数量。
样例 #1
样例输入
1
2
3
4
54 5
0 0 1 1 0
1 1 0 1 0
1 1 0 0 0
0 0 0 0 0样例输出
12样例 #2
样例输入
1
2
3
4
54 5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1样例输出
12样例解释
没有'0'(水),全都是'1'(陆地),也按一个岛屿计算。
数据范围
\(1\) ≤ \(m,n\)≤ \(200\)
题解
深搜板子题。
使用bfs的思想:枚举每一个位置的元素,如果是0就跳过,如果是1就使用bfs查询与该位置相邻的4个元素(前提是不出界),判断是否为1,如果是1那么继续查询,直到整个1块访问完毕。而为了避免走回头路可以定义一个bool数组inq(即in queue的缩写)来记录每个位置是否在bfs中已经入过队。
[!TIP]
对于当前位置(x,y)而言,可以设置两个增量数组来访问相邻的4个位置。
1
2int X[]={0,0,1,-1};
int Y[]={1,-1,0,0};分别对应(x,y+1) (x,y-1) (x+1,y) (x-1,y)
这样就可以用for循环去枚举4个方向,以确定当前坐标(nowX,nowY)相邻的4个位置
1
2
3
4for(int i=0;i<4;i++){
newX=nowX+X[i];
newY=nowY+Y[i];
}
1 | |
也可以使用DFS来实现。
1 | |