读数消融判定
蔚来技术岗 8月17号笔试 第一题
题目内容
产线侧在工位上部署了测点,回传一条长度为 nnn 的整型读数序列 {v1,v2,...,vn}\{v_1,v_2,\dots,v_n\}{v1,v2,...,vn}。质检模块每次可任选两个不同下标 p,qp,qp,q(p≠qp\neq qp=q):若 ∣vp−vq∣≤1|v_p-v_q|\le 1∣vp−vq∣≤1,即两读数相等或恰相差 111,则抹去其中较大的那条;两读数相等时任抹其一。请判断能否经过若干次上述抹除,使序列最终只剩一条读数。
输入描述
第一行一个整型 kkk(1≤k≤10001 \le k \le 10001≤k≤1000),表示随后有 kkk 条读数序列。
对其中每一条序列:
- 第一行一个整型 nnn(2≤n≤12002 \le n \le 12002≤n≤1200),表示该序列长度。
- 第二行 nnn 个正整型 v1,v2,...,vnv_1, v_2, \dots, v_nv1,v2,...,vn(1≤vi≤2501 \le v_i \le 2501≤vi≤250),表示各测点读数。
请对每条序列逐一判定能否消融到只剩一条读数。
输出描述
共写出 kkk 行。对每一条序列,若可以消融到只剩一条读数,写出 YES;否则写出 NO。
示例 1
输入
3
3
2 3 4
2
5 7
6
1 2 2 3 3 4
输出
YES
NO
YES
说明
第一条 {2,3,4}\{2,3,4\}{2,3,4}:选 333 与 444 抹去 444,再选 222 与 333 抹去 333,剩 222。
第二条 {5,7}\{5,7\}{5,7}:∣5−7∣=2|5-7|=2∣5−7∣=2,无法操作,不能消到一条。
第三条 {1,2,2,3,3,4}\{1,2,2,3,3,4\}{1,2,2,3,3,4}:可先抹去 444(与某个 333 配对),再抹去两个 333(分别与 222 配对),再抹去多余的 222(与 111 配对),最后剩 111。
示例 2
输入
2
4
8 8 10 9
3
1 1 3
输出
YES
NO
说明
第一条:选 101010 与 999 抹去 101010,得到 {8,8,9}\{8,8,9\}{8,8,9};再选 999 与某个 888 抹去 999,得到 {8,8}\{8,8\}{8,8};再抹去其中一个 888,剩 888。
第二条:只能把两个 111 配成一对并抹去其中一个,得到 {1,3}\{1,3\}{1,3};此时 ∣1−3∣=2|1-3|=2∣1−3∣=2,无法继续,最终剩两条。
题解和思路
思路
实现思路:模拟
- 题目可以直接忽略每个数出现次数,只需要考虑数是否出现,因为
两读数相等时任抹其一, 通过组合可以达到每个数只出现一次。 - 所以采用
flag数组存储每个[1, 250]每个数是否出现。然后从后往前遍历,当flag[i] = true时,判断flag[i-1]是否存在,不存在的话,不能消除数量 + 1. - 最终判断不能消除数量是否小于等于1. 满足输出
YES反之输出NO - 算法平均时间复杂度为
O(nk)
C++
cpp
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int k;
cin >> k;
while (k--) {
// 标记指定数是否出现
vector<bool> flag(251, false);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
flag[x] = true;
}
int total = 0;
for (int i = 250; i >= 1; i--) {
if (!flag[i]) {
continue;
}
// 不能被消除
if (i - 1 == 0 || !flag[i-1]) {
total++;
}
}
cout << (total <= 1 ? "YES" : "NO") << endl;
}
return 0;
}
Java
java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder out = new StringBuilder();
int k = Integer.parseInt(br.readLine().trim());
while (k-- > 0) {
// 标记指定数是否出现
boolean[] flag = new boolean[251];
int n = Integer.parseInt(br.readLine().trim());
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
int x = Integer.parseInt(st.nextToken());
flag[x] = true;
}
int total = 0;
for (int i = 250; i >= 1; i--) {
if (!flag[i]) {
continue;
}
// 不能被消除
if (i - 1 == 0 || !flag[i - 1]) {
total++;
}
}
out.append(total <= 1 ? "YES" : "NO").append('\n');
}
System.out.print(out);
}
}
python
python
import sys
data = list(map(int, sys.stdin.buffer.read().split()))
idx = 0
k = data[idx]
idx += 1
ans = []
while k > 0:
k -= 1
# 标记指定数是否出现
flag = [False] * 251
n = data[idx]
idx += 1
for i in range(n):
x = data[idx]
idx += 1
flag[x] = True
total = 0
for i in range(250, 0, -1):
if not flag[i]:
continue
# 不能被消除
if i - 1 == 0 or not flag[i - 1]:
total += 1
ans.append("YES" if total <= 1 else "NO")
sys.stdout.write("\n".join(ans))
Javascript
js
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const lines = [];
rl.on("line", (line) => {
lines.push(line.trim());
});
rl.on("close", () => {
let lineIndex = 0;
const k = Number(lines[lineIndex++]);
const ans = [];
for (let t = 0; t < k; t++) {
// 标记指定数是否出现
const flag = new Array(251).fill(false);
const n = Number(lines[lineIndex++]);
const values = lines[lineIndex++].split(/\s+/).map(Number);
for (let i = 0; i < n; i++) {
const x = values[i];
flag[x] = true;
}
let total = 0;
for (let i = 250; i >= 1; i--) {
if (!flag[i]) {
continue;
}
// 不能被消除
if (i - 1 === 0 || !flag[i - 1]) {
total++;
}
}
ans.push(total <= 1 ? "YES" : "NO");
}
console.log(ans.join("\n"));
});
Go
go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var k int
fmt.Fscan(in, &k)
for ; k > 0; k-- {
// 标记指定数是否出现
flag := make([]bool, 251)
var n int
fmt.Fscan(in, &n)
for i := 0; i < n; i++ {
var x int
fmt.Fscan(in, &x)
flag[x] = true
}
total := 0
for i := 250; i >= 1; i-- {
if !flag[i] {
continue
}
// 不能被消除
if i-1 == 0 || !flag[i-1] {
total++
}
}
if total <= 1 {
fmt.Fprintln(out, "YES")
} else {
fmt.Fprintln(out, "NO")
}
}
}