Weekly Contest 121

赛后总结:数学分析能力还是太差,这点抓紧拾起数学一些相关的知识点,新的一年希望有所突破吧。D 题赛后才想明白,如果这块知识点熟悉的话,也是一道纯秒题。新的一年在工作的同时,不断提升自己的算法能力吧。加油吧,老人。

1. String Without AAA or BBB

解题思路:构造即可

func strWithout3a3b(A int, B int) string {
	if A == 0 && B == 0 {
		return ""
	}

	var res []byte
	for i := 0; i < minInt(A, B); i++ {
		if A > B && i < A-B {
			res = append(res, 'a')
			res = append(res, 'a')
			res = append(res, 'b')
		} else if B > A && i < B-A {
			res = append(res, 'b')
			res = append(res, 'b')
			res = append(res, 'a')
		} else {
			res = append(res, 'a')
			res = append(res, 'b')
		}
	}
	if A > B {
		for i := 0; i < A-2*B; i++ {
			res = append(res, 'a')
		}
	} else if B > A {
		for i := 0; i < B-2*A; i++ {
			res = append(res, 'b')
		}
	}
	return string(res)
}

2. Time Based Key-Value Store

解题思路:由于 set 操作是严格按照 timestamp 升序进行的,因此我们只需要按照 key 分类存储,get 时候二分查找即可。这道题熟悉了 go 中 sort.Search 的用法,比赛的时候卡了一下。。。

type Node struct {
	timestamp int
	val       string
}

type TimeMap struct {
	db map[string][]Node
	is map[string]struct{}
}

/** Initialize your data structure here. */
func Constructor() TimeMap {
	return TimeMap{
		db: map[string][]Node{},
		is: map[string]struct{}{},
	}
}

func (this *TimeMap) Set(key string, value string, timestamp int) {
	this.db[key] = append(this.db[key], Node{timestamp, value})
	this.is[key] = struct{}{}
}

func (this *TimeMap) Get(key string, timestamp int) string {
	if _, ok := this.is[key]; !ok {
		return ""
	}
	if this.db[key][0].timestamp > timestamp {
		return ""
	}
	// 加深了 golang 中 对 sort.Search 二分查找的使用
	// 返回最小的满足条件的 idx
	idx := sort.Search(len(this.db[key]), func(i int) bool {
		return this.db[key][i].timestamp > timestamp
	})
	idx--
	return this.db[key][idx].val
}
3. Minimum Cost For Tickets

解题思路:简单动态规划。

const (
	inf  = 0x3f3f3f3f
	maxn = 400
)

func minInt(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func mincostTickets(days []int, costs []int) int {
	n := len(days)
	if n == 0 {
		return 0
	}
	dp := [maxn][3]int{}
	dp[0][0] = costs[0]
	dp[0][1] = costs[1]
	dp[0][2] = costs[2]
	for i := 1; i < n; i++ {
		dp[i][0] = costs[0] + minInt(minInt(dp[i-1][0], dp[i-1][1]), dp[i-1][2])
		j := i
		for j >= 0 && days[j] >= days[i]-6 {
			j--
		}
		if j < 0 {
			dp[i][1] = costs[1]
		} else {
			dp[i][1] = costs[1] + minInt(minInt(dp[j][0], dp[j][1]), dp[j][2])
		}
		j = i
		for j >= 0 && days[j] >= days[i]-29 {
			j--
		}
		if j < 0 {
			dp[i][2] = costs[2]
		} else {
			dp[i][2] = costs[2] + minInt(minInt(dp[j][0], dp[j][1]), dp[j][2])
		}
	}
	return minInt(minInt(dp[n-1][0], dp[n-1][1]), dp[n-1][2])
}
4. Triples with Bitwise AND Equal To Zero

解题思路:这题赛后才想明白的,果真是弱。。。这题直接求 A[i] & A[j] & A[k] = 0的方案数比较困难,我们尝试换种思路。三元组的总方案数为 n^3,求解 A[i] & A[j] & A[j] > 0的方案数比较容易。题目中输入元素的取值范围为 0 <= A[i] < 2^16,因此对于 A[i] & A[j] & A[k] > 0的结果肯定在[1,(1<<16)-1]区间内。假设 Bi 表示 A[i] & A[j] & A[j]结果的第i位为1的方案数,容易知道对于 A[i] & A[j] & A[k] > 0的结果必然属于集合|B1 U B2 U ... B15|。因此,对于指定的输入元素集合,只需要求解出|B1 U B2 U ... B15|的方案数,然后总方案数减去其方案数即可。对于|B1 U B2 ... U B15|方案数的求解采用容斥原理即可。

func countTriplets(A []int) int {

	if len(A) == 0 {
		return 0
	}

	n := len(A)
	ans := n * n * n
	for i := 1; i < (1 << 16); i++ {
		sign := 1
		x := i
		for x > 0 {
			x &= (x - 1)
			sign *= -1
		}

		cnt := 0
		for j := 0; j < n; j++ {
			if A[j]&i == i {
				cnt++
			}
		}
		ans += sign * cnt * cnt * cnt
	}
	return ans
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值