拼多多笔试真题-多多的灰度发布(C++/Py/Java /Js/Go)

多多的灰度发布

拼多多技术岗 7月19号笔试 第一题

题目内容

多多在维护一批编号 1 , 2 , ... , n 1,\ 2,\ \dots,\ n 1, 2, ..., n 排列的实例。每个实例只有两种状态: 0 0 0 表示使用旧版本, 1 1 1 表示使用新版本。

多多在灰度发布平台执行了一次操作:

  1. 选择一个非空连续区间 L , R L,\\ R L, R
  2. 选择一个目标状态 v v v,其中 v v v 为 0 0 0 或 1 1 1
  3. 把区间内所有实例的状态都设为 v v v
    区间中可以包含原本就已经处于状态 v v v 的实例,但这次操作必须至少改变一个实例的状态。发布前后的实例状态串 A A A 和 B B B 被完整保留,但操作日志丢失了,保证至少存在一种操作,可以把 A A A 变为 B B B。
    请判断这次操作能否被唯一确定。若合法的三元组 ( L , R , V ) (L,\ R,\ V) (L, R, V) 恰好只有一个,输出它,否则输出 − 1 -1 −1。 注意:只要 L 、 R L、R L、R 或 V V V 中有任意一项不同,就视为不同的操作,即使它们得到的发布后状态完全相同。

输入描述

第一行包含一个正整数 T T T,表示测试用例的数量。

对于每个测试用例:

第一行包含一个整数 n n n,表示实例数量。

第二行包含一个长度为 n n n 的 01 01 01 串 A A A,表示发布前的状态。

第三行包含一个长度为 n n n 的 01 01 01 串 B B B,表示发布后的状态。

输出描述

对于每个测试用例:

如果操作唯一,输出一行三个整数 L R V L\ R\ V L R V。

如果不存在唯一操作,输出一行 − 1 -1 −1。

补充说明:

  • 1 ≤ T ≤ 10 1 \le T \le 10 1≤T≤10
  • A A A 和 B B B 均为长度恰好为 n n n 的 01 01 01 串;
  • 单个输入文件中,所有测试用例的 n n n 之和不超过 2 ∗ 10 5 2 * 10^5 2∗105;
  • 保证每组数据至少存在一种合法操作。

样例1

输入

复制代码
6
5
00000
01110
5
01000
01110
6
111111
100001
7
0001000
0111110
1
0
1
5
00010
01110

输出

复制代码
2 4 1
-1
2 5 0
2 6 1
1 1 1
-1

题解和思路

思路

实现思路:逻辑分析

  1. 对于每组输入,通过遍历发布前/后字符串找到对应start 第一个不同位置end 最后一个不同的位置
  2. 根据第一步得出start和end可以完成一下判断
    • start = -1,说明发布前/后字符串完全相同,不存在唯一解。
    • 将发布前变更为发布后,唯一可能的v就是`Bstart, 判断start, end是否全为v,不全为v说明根本无法通过一次操作将发布前变更为发布后。
    • 由于区间中可以包含原本就已经处于状态 v v v 的实例,通过上面判断之后,可以得知start, end, v肯定是一个合法操作。要保证是否唯一,主要看是否能够进行区间左右扩展。
      • B[start - 1] == v说明能往左侧扩展,答案不唯一
      • B[end-+1] == v说明能往右侧扩展,答案不唯一
  3. 算法平均时间复杂度为O(n)

C++

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        string A,B;
        cin >> A;
        cin >> B;
        
        // 不同的开始和结束位置
        int start = -1;
        int end = -1;
        for (int i = 0; i < n; i++) {
            if (A[i] != B[i]) {
                if (start == -1) {
                    start = i;
                }
                end = i;
            }
        }
        // 没有变化,不存在合法操作
        if (start == -1) {
            cout << -1 << endl;
            continue;
        }
        
        // 确定v
        int v = B[start] - '0';
        bool ok = true;
        
        // 判断B [start,end]是否都为v v肯定为B[start]
        for (int i = start; i <= end; i++) {
            if (B[i] != B[start]) {
                ok = false;
                break;
            }
        }
        // 左右扩展,判断是否唯一
        if (ok && start > 0 && B[start - 1] == B[start]) {
            ok = false;
        }
        
        if (ok && end < n - 1 && B[end + 1] == B[start]) {
            ok = false;
        }
        
        // 不唯一
        if (!ok) {
            cout << -1 << endl;
        } else {
            cout << start + 1 << " " << end + 1 << " " << B[start] - '0' << endl;
        }
    }
    return 0;
}

Java

java 复制代码
import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int T = sc.nextInt();

        while (T-- > 0) {
            int n = sc.nextInt();
            String A = sc.next();
            String B = sc.next();

            // 不同的开始和结束位置
            int start = -1;
            int end = -1;
            for (int i = 0; i < n; i++) {
                if (A.charAt(i) != B.charAt(i)) {
                    if (start == -1) {
                        start = i;
                    }
                    end = i;
                }
            }

            // 没有变化,不存在合法操作
            if (start == -1) {
                System.out.println(-1);
                continue;
            }

            // 确定v
            int v = B.charAt(start) - '0';
            boolean ok = true;

            // 判断B[start,end]是否都为v,v肯定为B[start]
            for (int i = start; i <= end; i++) {
                if (B.charAt(i) != B.charAt(start)) {
                    ok = false;
                    break;
                }
            }

            // 左右扩展,判断是否唯一
            if (ok && start > 0 && B.charAt(start - 1) == B.charAt(start)) {
                ok = false;
            }

            if (ok && end < n - 1 && B.charAt(end + 1) == B.charAt(start)) {
                ok = false;
            }

            // 不唯一
            if (!ok) {
                System.out.println(-1);
            } else {
                System.out.println((start + 1) + " " + (end + 1) + " " + v);
            }
        }
    }
}

python

python 复制代码
T = int(input())

for _ in range(T):
    n = int(input())
    A = input().strip()
    B = input().strip()

    # 不同的开始和结束位置
    start = -1
    end = -1
    for i in range(n):
        if A[i] != B[i]:
            if start == -1:
                start = i
            end = i

    # 没有变化,不存在合法操作
    if start == -1:
        print(-1)
        continue

    # 确定v
    v = int(B[start])
    ok = True

    # 判断B[start,end]是否都为v,v肯定为B[start]
    for i in range(start, end + 1):
        if B[i] != B[start]:
            ok = False
            break

    # 左右扩展,判断是否唯一
    if ok and start > 0 and B[start - 1] == B[start]:
        ok = False

    if ok and end < n - 1 and B[end + 1] == B[start]:
        ok = False

    # 不唯一
    if not ok:
        print(-1)
    else:
        print(start + 1, end + 1, v)

Javascript

js 复制代码
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const input = [];

rl.on("line", (line) => {
    input.push(line);
});

rl.on("close", () => {
    let idx = 0;
    const T = Number(input[idx++]);

    const ans = [];

    for (let t = 0; t < T; t++) {
        const n = Number(input[idx++]);
        const A = input[idx++];
        const B = input[idx++];

        // 不同的开始和结束位置
        let start = -1;
        let end = -1;
        for (let i = 0; i < n; i++) {
            if (A[i] !== B[i]) {
                if (start === -1) {
                    start = i;
                }
                end = i;
            }
        }

        // 没有变化,不存在合法操作
        if (start === -1) {
            ans.push("-1");
            continue;
        }

        // 确定v
        const v = Number(B[start]);
        let ok = true;

        // 判断B[start,end]是否都为v,v肯定为B[start]
        for (let i = start; i <= end; i++) {
            if (B[i] !== B[start]) {
                ok = false;
                break;
            }
        }

        // 左右扩展,判断是否唯一
        if (ok && start > 0 && B[start - 1] === B[start]) {
            ok = false;
        }

        if (ok && end < n - 1 && B[end + 1] === B[start]) {
            ok = false;
        }

        // 不唯一
        if (!ok) {
            ans.push("-1");
        } else {
            ans.push(`${start + 1} ${end + 1} ${v}`);
        }
    }

    console.log(ans.join("\n"));
});

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	in := bufio.NewReader(os.Stdin)

	var T int
	fmt.Fscan(in, &T)

	for ; T > 0; T-- {
		var n int
		fmt.Fscan(in, &n)

		var A, B string
		fmt.Fscan(in, &A)
		fmt.Fscan(in, &B)

		// 不同的开始和结束位置
		start := -1
		end := -1
		for i := 0; i < n; i++ {
			if A[i] != B[i] {
				if start == -1 {
					start = i
				}
				end = i
			}
		}

		// 没有变化,不存在合法操作
		if start == -1 {
			fmt.Println(-1)
			continue
		}

		// 确定v
		v := int(B[start] - '0')
		ok := true

		// 判断B[start,end]是否都为v,v肯定为B[start]
		for i := start; i <= end; i++ {
			if B[i] != B[start] {
				ok = false
				break
			}
		}

		// 左右扩展,判断是否唯一
		if ok && start > 0 && B[start-1] == B[start] {
			ok = false
		}

		if ok && end < n-1 && B[end+1] == B[start] {
			ok = false
		}

		// 不唯一
		if !ok {
			fmt.Println(-1)
		} else {
			fmt.Println(start+1, end+1, v)
		}
	}
}
相关推荐
市象17 天前
新拼姆会是大号版“SHEIN”吗?
拼多多
无限码力20 天前
拼多多笔试真题【多多的特殊三元组】
拼多多·拼多多笔试真题·拼多多笔试题库·拼多多技术岗笔试·pdd笔试笔试真题
无限码力20 天前
拼多多笔试真题-多多的Boss挑战(C++/Py/Java /Js/Go)
拼多多·拼多多笔试真题·拼多多技术岗笔试题目·拼多多机试·pdd笔试真题
无限码力21 天前
拼多多笔试真题-多多捕蝇(C++/Py/Java /Js/Go)
拼多多·拼多多笔试真题·拼多多技术岗笔试题目·拼多多机试·pdd笔试真题
无限码力25 天前
拼多多笔试真题-多多的营救行动(C++/Py/Java /Js/Go)
拼多多·拼多多笔试真题·拼多多笔试题库·拼多多技术岗笔试
无限码力1 个月前
拼多多笔试真题-对角线遍历矩阵(C++/Py/Java /Js/Go)
矩阵·拼多多·拼多多笔试真题·拼多多技术岗笔试题目·拼多多机试
27669582921 年前
拼多多小程序 anti_content 分析
java·javascript·python·node·拼多多·anti-content·anti_content
27669582921 年前
拼多多 anti-token unidbg 分析
java·python·go·拼多多·pdd·pxx·anti-token
市象2 年前
独家|安克Temu平台闭店,或遭遇亚马逊“二选一”
亚马逊·temu·拼多多