package misc import "testing" // 题目(推测题干) // // 给定两个长度为 n 的 0/1 数组 a 和 b。 // 一次操作:选择 [L, R, V],满足 1 ≤ L ≤ R ≤ n,V ∈ {0,1}, // 将 a 中下标在 [L,R] 内的所有元素统一修改为 V(区间外不变)。 // // 问:是否存在恰好一种操作使 a 变为 b? // - 存在且唯一:输出该操作 [L,R,V](0-indexed 闭区间) // - 不存在或不唯一:输出 -1 // // 思路(0-indexed) // // 记 need = { i : a[i] != b[i] },即必须被改到的位置。 // // 1. 找 lo = min(need), hi = max(need)。need 为空 → a == b,特判(见下)。 // 2. 区间 [L,R] 必须 ⊇ [lo, hi],否则 need 中落在区间外的位置不会被改。 // 3. 区间内每个位置改完都要等于 b;而一个操作只有一个 V, // 所以 [lo,hi] 内 b 必须全相同,V = b[lo]。否则无解 (-1)。 // 4. L 的取值范围:L ≤ lo。向左能扩张到 b 中连续等于 V 的位置 // (这些位置改后仍等于 b,不破坏)。 // - L 唯一 ⟺ lo == 0(到左边界)或 b[lo-1] != V(左边紧邻不等于 V,无法扩张) // 5. R 的取值范围:R ≥ hi。向右能扩张到 b 中连续等于 V 的位置。 // - R 唯一 ⟺ hi == n-1(到右边界)或 b[hi+1] != V // 6. L、R 都唯一 → 输出 [lo, hi, V];否则 -1。 // // 特判 a == b(need 为空): // - 要一次操作让 a 不变:区间内 a 必须全等于 V。 // - 任何单点 [i,i] 配 V=a[i] 都可行。 // - n == 1:唯一解 [0, 0, a[0]]。 // - n >= 2:有多个单点选择 → 不唯一 → -1。 func uniqueRangeAssign(a, b []int) (L, R, V int, ok bool) { n := len(a) // 第 1 步:找 lo, hi lo, hi := -1, -1 for i := 0; i < n; i++ { if a[i] != b[i] { if lo == -1 { lo = i } hi = i } } // 特判 a == b if lo == -1 { if n == 1 { return 0, 0, a[0], true } return 0, 0, 0, false } // 第 3 步:V = b[lo],检查 [lo,hi] 内 b 全等于 V V = b[lo] for i := lo; i <= hi; i++ { if b[i] != V { return 0, 0, 0, false } } // 第 4 步:L 唯一性 lOK := lo == 0 || b[lo-1] != V // 第 5 步:R 唯一性 rOK := hi == n-1 || b[hi+1] != V if !lOK || !rOK { return 0, 0, 0, false } // 第 6 步:唯一解 return lo, hi, V, true } func TestUniqueRangeAssign(t *testing.T) { cases := []struct { name string a, b []int wantL int wantR int wantV int wantOK bool }{ {"唯一-全改", []int{0, 0}, []int{1, 1}, 0, 1, 1, true}, {"唯一-部分改", []int{0, 0, 0, 0, 0}, []int{1, 1, 1, 0, 0}, 0, 2, 1, true}, {"唯一-右扩", []int{0, 0, 0, 0, 0}, []int{0, 0, 1, 1, 1}, 2, 4, 1, true}, {"无解-内部b不一致", []int{0, 1, 0}, []int{1, 0, 1}, 0, 0, 0, false}, {"不唯一-R可扩", []int{0, 1, 1}, []int{1, 1, 1}, 0, 0, 0, false}, {"不唯一-L可扩", []int{1, 0, 1}, []int{1, 1, 1}, 0, 0, 0, false}, {"不唯一-a=b,n>=2", []int{1, 1, 1}, []int{1, 1, 1}, 0, 0, 0, false}, {"唯一-a=b,n=1", []int{0}, []int{0}, 0, 0, 0, true}, {"唯一-单点改", []int{0}, []int{1}, 0, 0, 1, true}, {"唯一-覆盖整个数组", []int{1, 1, 0, 1}, []int{0, 0, 0, 0}, 0, 3, 0, true}, {"无解-need不连续且b不一致", []int{0, 0, 0, 0}, []int{1, 0, 0, 1}, 0, 0, 0, false}, } for _, c := range cases { L, R, V, ok := uniqueRangeAssign(c.a, c.b) pass := ok == c.wantOK && (!ok || (L == c.wantL && R == c.wantR && V == c.wantV)) if !pass { t.Errorf("%s: a=%v b=%v -> [%d,%d,%d] ok=%v, want [%d,%d,%d] ok=%v", c.name, c.a, c.b, L, R, V, ok, c.wantL, c.wantR, c.wantV, c.wantOK) } } }