#P1166. 第1题-换座位
-
1000ms
Tried: 507
Accepted: 239
Difficulty: 4
所属公司 :
美团
时间 :2023年4月8日
-
算法标签>模拟
第1题-换座位
思路:暴力模拟
对于每个人,其大行和大列每次增加 1,假设当前位置为 (i,j),则下一次位置为 (i+1,j+1)。小列每次不变,故比较这两个位置中小列不同的即可。
时间复杂度:O(nma)
类似题目推荐
点评:总体来讲,一道比较简单的签到题。这里主要总结了各个公司2022/23年的类似的不需要脑子的暴力签到题
LeetCode
往届Leetcode周赛/双周赛的第一题
CodeFun2000
1.P1041 华为od-面试真题 2022.10.9-句子的平均重量
2.P1118 阿里巴巴 2023.03.26-第二题-报数字
3.P1174 华为od 2023.04.08--第一题-箱子之形摆放
4.P1175 华为od 2023.04.08--第二题-新学校选址
5.P1246 美团 2023.04.23-春招-第二题-制作骰子
代码
技巧使用
1.循环移位(circular shift)
对于矩阵中的每一个元素,因为需要和右下方的元素进行比较。所以为了避免数组下标越界,使用取模运算来实现循环移位。
2.逻辑等
ans += (s[i][j][k] != s[(i + 1) % n][(j + 1) % m][k])
这样的表达式省去了写if , else 的逻辑。但是工程项目中是否推荐使用,待商榷。
C++
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, m, a;
cin >> n >> m >> a;
vector<vector<string>> s(n, vector<string>(m));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> s[i][j];
int ans = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j) {
string& s1 = s[i][j];
// 取模
string& s2 = s[(i + 1) % n][(j + 1) % m];
for (int k = 0; k < a; ++k) {
ans += (s1[k] != s2[k]);
}
}
cout << ans << "\n";
return 0;
}
python
n, m, a = map(int, input().split(" "))
s = [[] for i in range(n)]
for i in range(n):
s[i] = input().split(" ")
ans = 0
for i in range(n):
for j in range(m):
for k in range(a):
# 利用 逻辑表达式 + 取模 简化代码
ans += (s[i][j][k] != s[(i + 1) % n][(j + 1) % m][k])
print(ans)
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int a = scanner.nextInt();
String[][] s = new String[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
s[i][j] = scanner.next();
}
}
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int k = 0; k < a; k++) {
// 利用 逻辑表达式 + 取模 简化代码
ans += (s[i][j].charAt(k) != s[(i + 1) % n][(j + 1) % m].charAt(k)) ? 1 : 0;
}
}
}
System.out.println(ans);
}
}
Go
package main
import (
"os"
"fmt"
"bufio"
)
func main(){
in:=bufio.NewReader(os.Stdin)
var n,m,a int
fmt.Fscan(in,&n,&m,&a)
v:=make([][]string,n+1)
for i:=0;i<n;i++{
v[i]=make([]string,m+1)
for j:=0;j<m;j++{
fmt.Fscan(in,&v[i][j])
}
}
ans:=0
for i:=0;i<n;i++{
for j:=0;j<m;j++{
var s,e string
s=v[i][j]
// 取模技巧
e=v[(i+1)%n][(j+1)%m]
for k:=0;k<len(s);k++{
if s[k]!=e[k]{
ans++
}
}
}
}
fmt.Println(ans)
}
Js
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';
process.stdin.on('data', (data) => {
input += data;
return;
});
process.stdin.on('end', () => {
const lines = input.trim().split('\n');
const [n, m, a] = lines[0].trim().split(' ').map(x => Number(x));
const s = new Array(n);
for (let i = 0; i < n; ++i) {
s[i] = lines[i + 1].trim().split(' ');
}
let ans = 0;
for (let i = 0; i < n; ++i) {
for (let j = 0; j < m; ++j) {
const s1 = s[i][j];
// 取模
const s2 = s[(i + 1) % n][(j + 1) % m];
for (let k = 0; k < a; ++k) {
ans += (s1[k] !== s2[k]);
}
}
}
console.log(ans);
});
题目内容
小美所在的班级是一所小学,在教学楼的二楼。教学楼共有三个楼层,一楼是食堂和礼堂,二楼和三楼则是教室。小美的班级坐落在教学楼的正中央,小美班级的座位排成了 n 行(行从 1 到 n 编号),共有 m 个大列(大列从 1 到 m 编号),每个大列中有 a 个小列(小列从 1 到 a 编号),大列与大列之间有一个过道。
班主任规定每周进行一次座位调整,为了使同学们有机会结交不同的同学,每周的座位调整遵循特定的规则,具体规则如下:
- 首先所有同学都换到后一行,最后一行的同学换到第一行。即对于坐在第 i<n 行的同学,新位置在第 i+1 行,如果 i=n ,那么新位置在第一行;
- 然后所有同学都移动到自己右边的那个大列的相同小列上,在最右大列的同学移动到最左大列。即对于坐在第 j<m 大列的同学,新位置在第 j+1 大列,如果 j=m ,那么新位置在第一大列;对于坐在第 k 小列的同学,新位置仍然在第 k 小列。
然而,学校最近购进了新型的学生桌椅,这些桌椅可以调节高度,有些同学把桌子的高度调高了,而有些同学则没有。于是,在座位调整后,如果一位调整过桌子高度的同学坐到了没有调整过桌子高度的同学的位置,他会调整新位置的桌子到他想要的高度;同样地,如果一位没有调整过桌子高度的同学坐到了调整过桌子高度同学的位置,他也会调整新位置的桌子高度,使其恢复原高度。
现在小美的班级要进行换座位了,给出换座位前班级所有桌子的情况,小美想知道,换一次位置后,有多少同学需要重新调整桌子高度。
输入描述
输入第一行包含三个数 n , m , a ,意义如题目所示。
接下来 n 行,每行 m 个长度为 a 的 01 字符串,表示目前小美班上的桌子情况。其中 0 表示这个位置未调节桌子高度,1 表示已调节桌子高度。
对于全部数据, 1≤n,m≤200,n×m≥2,1≤a≤5
输出描述
输出一行一个整数,表示换座位后有多少同学需要重新调整桌子高度。
样例
输入
3 3 2
01 10 00
10 00 11
01 00 00
输出
8