A - Suspension

简单

B - Split

对每个数字出现的次数分类

出现奇数次:
    一定且只可以贡献一次,因为总数是偶数,所以出现奇数的数字也一定是偶数个,不会导致两个数组长度不一致的影响
出现偶数次:
    除以2结果为奇数的:一定且可以贡献两次
    除以2结果为偶数的: 依照4次为例子,只能按照一个列表放1个,一个列表放3个,那么存放1个数的列表,怎么补充数字让两个数列长度相等呢?
        a. 另找一个长度为4的数字,反着放数量,两两组合就可以
        b. 让出现奇数次的数去填充,因为他们放哪个数列都能生效
package main

import (
	"fmt"
)

func solve() {
	var n int
	var numMap map[int]int = make(map[int]int)
	fmt.Scan(&n)
	for i := 0; i < 2*n; i++ {
		var x int
		fmt.Scan(&x)
		numMap[x]++
	}

	var res int
	var fourCount int
	var oddCount int
	for _, count := range numMap {
		if count%2 == 0 {
			if count%4 == 0 {
				fourCount++
				continue
			}
			res += 2
		} else {
			res += 1
			if count > 1 {
				oddCount += count - 2
			} else {
				oddCount++
			}
		}
	}
	res += fourCount / 2 * 4
	if fourCount%2 == 1 && oddCount >= 2 {
		res += 2
	}
	// fmt.Println("--> ", res)
	fmt.Println(res)
}

func main() {
	var t int
	fmt.Scan(&t)
	for i := 0; i < t; i++ {
		solve()
	}
}
C - Annoying Game
Alice and Bob都只会做最优操作,且因为既能 Ai+Bi 又能 Ai-Bi,所以两者还能做对方的相反操作
所以一旦Alice在任意一个数上做了加操作且最优,Bob为了阻止她,只能再减掉相同的结果
那么最后当操作数k
为偶数:
	则数列结果不变,算最大连续子序列和,
为基数:
	则Alice只能操作一次,算作最大连续子序列和的变种,推导一个新的dp过程
package main

import (
	"fmt"
)

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func solve() {
	var n, k int
	fmt.Scan(&n, &k)
	var arr []int = make([]int, n, n)
	for i := 0; i < n; i++ {
		fmt.Scan(&arr[i])
	}
	var brr []int = make([]int, n, n)
	for i := 0; i < n; i++ {
		fmt.Scan(&brr[i])
	}

	if k%2 == 0 {
		var pre, res int = -10000000000000, -10000000000000
		for i := 0; i < n; i++ {
			pre = max(pre+arr[i], arr[i])
			res = max(res, pre)
		}
		// fmt.Println("+++", res)
		fmt.Println(res)
	} else {
		var pre, preAdd, res int = -10000000000000, -10000000000000, -10000000000000
		for i := 0; i < n; i++ {
			oldPre, oldPreAdd := pre, preAdd
			pre = max(oldPre+arr[i], arr[i])
			preAdd = max(pre+brr[i], oldPreAdd+arr[i])
			res = max(max(pre, preAdd), res)
		}
		// fmt.Println("+++", res)
		fmt.Println(res)
	}
}

func main() {
	var t int
	fmt.Scan(&t)
	for i := 0; i < t; i++ {
		solve()
	}
}
D - Palindrome Flipping
如果直接从s转为t,这里其实是比较难处理的。所以如果有一个中间状态保证他俩都能变过去,再反向记录t的操作过程就是了。
最简单的就是让s转成纯1或纯0字符串,再反转记录为t的操作过程。
其中我们还要发现一个规律,
1. 如果字符串长度为3,除了101和010不能反转外,其他任意01串都可以转为纯01串。
2. 那么当长度为4时,所有的01字符串都可以转为纯01串。为什么?
因为当在长度为3的01串后添加一个0或1他都能和末尾前一个或者两个字符组成回文。
比如1011,后两个为回文,0101,后三个为回文。
1011 -> 1000 -> 1111 
0101 -> 0010 -> 1110 -> 0000 -> 1111
3. 长度大于4的,都可以由前面先转为纯01串,再反转后一位获得
比如10110先把前四位转为 11110 -> 00000 -> 11111
由此可知推论,只要字符串长度大于等于4,都可以由开始四位字符串一步步反转为纯01串。
所以只要预处理所有四位字符串的反转过程,再顺序操作后续每一位字符就好了
package main

import (
	"fmt"
)

type Pair struct {
	l int
	r int
}

func checkPalindrome(s string, left int, right int) bool {
	for left >= 0 && right < len(s) && left <= right && s[left] == s[right] {
		left++
		right--
	}
	return left >= right
}

func reverseString(s string, left int, right int) string {
	var newS string
	for i := 0; i < left; i++ {
		newS += string(s[i])
	}
	for i := left; i <= right; i++ {
		if s[i] == '0' {
			newS += "1"
		} else {
			newS += "0"
		}
	}
	for i := right + 1; i < len(s); i++ {
		newS += string(s[i])
	}

	return newS
}

var fourLenRes []Pair

func dfs(s string, step int, resPair []Pair) {
	if s == "0000" {
		if len(fourLenRes) == 0 || len(resPair) < len(fourLenRes) {
			fourLenRes = resPair
		}
		return
	}

	if step > 5 {
		return
	}

	for i := 0; i < len(s); i++ {
		for j := i + 1; j < len(s); j++ {
			if checkPalindrome(s, i, j) {
				newS := reverseString(s, i, j)
				newPairs := make([]Pair, len(resPair))
				copy(newPairs, resPair)
				newPairs = append(newPairs, Pair{l: i + 1, r: j + 1})
				dfs(newS, step+1, newPairs)
			}
		}
	}
}

func getResPairs(s string, n int) []Pair {
	var resPair []Pair
	fourLenRes = []Pair{}
	dfs(s[0:4], 0, []Pair{})
	resPair = append(resPair, fourLenRes...)
	var lastZeroPos int = 3
	for i := 4; i < n; i++ {
		if s[i] == '1' && (i+1 == n || s[i+1] != '1') {
			resPair = append(resPair, Pair{l: 1, r: lastZeroPos + 1})
			resPair = append(resPair, Pair{l: 1, r: i + 1})
			lastZeroPos = i
		} else if s[i] == '0' {
			lastZeroPos = i
		}
	}
	return resPair
}

func solve() {
	var n int
	var s, t string
	fmt.Scan(&n)
	fmt.Scan(&s)
	fmt.Scan(&t)

	resS := getResPairs(s, n)
	resT := getResPairs(t, n)
	fmt.Println(len(resS) + len(resT))
	for _, p := range resS {
		fmt.Println(p.l, p.r)
	}
	for i := len(resT) - 1; i >= 0; i-- {
		fmt.Println(resT[i].l, resT[i].r)
	}
}

func main() {
	var t int
	fmt.Scan(&t)
	for i := 0; i < t; i++ {
		solve()
	}
}