蔚来笔试真题-读数消融判定(C++/Py/Java /Js/Go)

读数消融判定

蔚来技术岗 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,无法继续,最终剩两条。

题解和思路

思路

实现思路:模拟

  1. 题目可以直接忽略每个数出现次数,只需要考虑数是否出现,因为两读数相等时任抹其一, 通过组合可以达到每个数只出现一次。
  2. 所以采用flag数组存储每个[1, 250]每个数是否出现。然后从后往前遍历,当flag[i] = true时,判断flag[i-1]是否存在,不存在的话,不能消除数量 + 1.
  3. 最终判断不能消除数量是否小于等于1. 满足输出YES反之输出NO
  4. 算法平均时间复杂度为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")
		}
	}
}