Codeforces Round 785 (Div. 2) C && Leetcode1334
题目及来源
-
题目来源: 11月14日灵茶试炼 && 力扣每日一题
-
codeforces题目描述:
给你一个正整数 n n n 。如果某个不带前导零的正整数 a a a 的数位顺序颠倒后仍然不变,我们就称它为回折正整数 a a a 。求把 n n n 表示成正整数宫调整数之和的不同方法的数目。如果两种表达方式中至少有一个回折整数的频率不同,那么这两种表达方式就被认为是不同的。例如, 5 = 4 + 1 5=4+1 5=4+1 和 5 = 3 + 1 + 1 5=3+1+1 5=3+1+1 被认为是不同的,但 5 = 3 + 1 + 1 5=3+1+1 5=3+1+1 和 5 = 1 + 3 + 1 5=1+3+1 5=1+3+1 被认为是相同的。
从形式上看,你需要找出正宫调整数的和等于 n n n 的不同多集的个数。
由于答案可能很大,请打印出以 1 0 9 + 7 10^9+7 109+7 为模数的答案。
输入
第一行输入包含一个整数 t t t ( 1 ≤ t ≤ 1 0 4 1\leq t\leq 10^4 1≤t≤104 ),表示测试用例的数量。
每个测试用例都包含一行输入,其中包含一个整数 n n n ( 1 ≤ n ≤ 4 ⋅ 1 0 4 1\leq n\leq 4\cdot 10^4 1≤n≤4⋅104 ) - 所需的回文整数之和。
输出
为每个测试用例打印一个整数,表示所需的答案取模 1 0 9 + 7 10^9+7 109+7 。 -
Leetcode题目描述:
有 n 个城市,按从 0 到 n-1 编号。给你一个边数组 edges,其中 edges[i] = [fromi, toi, weighti] 代表 fromi 和 toi 两个城市之间的双向加权边,距离阈值是一个整数 distanceThreshold。
返回能通过某些路径到达其他城市数目最少、且路径距离 最大 为 distanceThreshold 的城市。如果有多个这样的城市,则返回编号最大的城市。
注意,连接城市 i 和 j 的路径的距离等于沿该路径的所有边的权重之和。
codeforces 题目思路
可以将回文数字预处理出来,处理方法就是将每一个数字都生成它的回文,由数据范围可知预处理的数字最大不超过400,之后将这些回文数字进行一个完全背包的过程。
预处理数字的值为m
时间复杂度:
O
(
n
∗
m
)
O(n * m)
O(n∗m)
空间复杂度:
O
(
n
+
m
)
O(n + m)
O(n+m)
Leetcode 题目思路
可以使用多源最短路算法floyd算法,或者使用单源最短路dijkstra算法跑多次,floyd算法和灵神学到了dp的思路,
d
f
s
(
k
,
i
,
j
)
dfs(k, i, j)
dfs(k,i,j) 定义为中间节点小于等于k的i到j的距离
d
f
s
(
k
,
i
,
j
)
=
m
i
n
(
d
f
s
(
k
−
1
,
i
,
k
)
,
d
f
s
(
k
−
1
,
i
,
k
)
+
d
f
s
(
k
−
1
,
k
,
j
)
)
dfs(k, i, j) = min(dfs(k - 1, i, k), dfs(k - 1, i, k) + dfs(k - 1, k, j))
dfs(k,i,j)=min(dfs(k−1,i,k),dfs(k−1,i,k)+dfs(k−1,k,j))
时间复杂度:
O
(
n
3
)
O(n^3)
O(n3)
空间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
codeforces代码
go语言版本代码
package main
import (
"bufio"
"container/heap"
. "fmt"
"os"
)
// func init() { debug.SetGCPercent(-1) } // 关闭垃圾收集
func run() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush() // 加速读取
var t, n int
var pal []int
const mod int = 1e9 + 7
for i := 1; i < 400; i++ {
p := i
for x := i / 10; x > 0; x /= 10 {
p = p*10 + x%10
}
pal = append(pal, p)
if i < 100 {
p := i
for x := i; x > 0; x /= 10 {
p = p*10 + x%10
}
pal = append(pal, p)
}
}
var f [40001]int
f[0] = 1
for _, v := range pal {
for j := v; j < len(f); j++ {
f[j] = (f[j] + f[j-v]) % mod
}
}
for Fscan(in, &t); t > 0; t-- {
Fscan(in, &n)
Fprintln(out, f[n])
}
}
func main() {
run()
}
Leetcode代码
go语言版本
// func findTheCity(n int, edges [][]int, distanceThreshold int) (ans int) {
// f := make([][]int, n)
// for i := range f {
// f[i] = make([]int, n)
// for j := range f[i] {
// f[i][j] = math.MaxInt >> 1
// }
// }
// for _, e := range edges {
// x, y, v := e[0], e[1], e[2]
// f[x][y] = v
// f[y][x] = v
// }
// for k := 0; k < n; k++ { // floyd算法
// for i := 0; i < n; i++ {
// for j := 0; j < n; j++ {
// f[i][j] = min(f[i][j], f[i][k]+f[k][j])
// }
// }
// }
// //var dfs func(int, int, int) int
// //dfs = func(k, i, j int) int {
// // if k < 0 {
// // return f[i][j]
// // }
// // p := &f[k][i][j]
// // if *p != 0 {
// // return *p
// // }
// // res := min(dfs(k-1, i, j), dfs(k-1, i, k)+dfs(k-1, k, j))
// // *p = res
// // return res
// //}
// minCnt := n
// for i, dis := range f {
// cnt := 0
// for j, d := range dis {
// if i != j && d <= distanceThreshold {
// cnt++
// }
// }
// if cnt <= minCnt {
// minCnt = cnt
// ans = i
// }
// }
// return
// }
func findTheCity(n int, edges [][]int, distanceThreshold int) (ans int) {
const inf int = 1e9 + 7
vis := make([]bool, n)
dist := make([]int, n)
g := make([][]int, n)
for i := range g {
g[i] = make([]int, n)
for j := range g[i] {
g[i][j] = inf
}
}
for _, e := range edges {
x, y, v := e[0], e[1], e[2]
g[x][y] = v
g[y][x] = v
}
dijkstra := func(u int) (cnt int) { //朴素的dijkstra
for i := range vis {
vis[i] = false
dist[i] = inf
}
dist[u] = 0
for i := 0; i < n; i++ {
k := -1
for j := 0; j < n; j++ {
if !vis[j] && (k == -1 || dist[j] < dist[k]) {
k = j
}
}
vis[k] = true
for j := 0; j < n; j++ {
dist[j] = min(dist[j], dist[k]+g[k][j])
}
}
for _, d := range dist {
if d <= distanceThreshold {
cnt++
}
}
return
}
minCnt := n
for i := 0; i < n; i++ {
if t := dijkstra(i); t <= minCnt {
minCnt = t
ans = i
}
}
return
}
dijkstra堆优化
func findTheCity(n int, edges [][]int, distanceThreshold int) (ans int) {
const inf int = 1e9 + 7
dist := make([]int, n)
g := make([][]pair, n)
for _, e := range edges {
x, y, v := e[0], e[1], e[2]
g[x] = append(g[x], pair{y, v})
g[y] = append(g[y], pair{x, v})
}
dijkstra := func(u int) (cnt int) { //朴素的dijkstra
for i := range dist {
dist[i] = inf
}
h := hp{}
heap.Push(&h, pair{u, 0})
for h.Len() > 0 {
p := heap.Pop(&h).(pair)
if dist[p.i] < inf {
continue
}
dist[p.i] = p.v
for _, p1 := range g[p.i] {
if dist[p1.i] == inf {
heap.Push(&h, pair{p1.i, p1.v + p.v})
}
}
}
for _, d := range dist {
if d <= distanceThreshold {
cnt++
}
}
return
}
minCnt := n
for i := 0; i < n; i++ {
if t := dijkstra(i); t <= minCnt {
minCnt = t
ans = i
}
}
return
}
type pair struct {
i, v int
}
type hp []pair
func (h *hp) Len() int {
return len(*h)
}
func (h *hp) Less(i, j int) bool {
a := *h
return a[i].v < a[j].v
}
func (h *hp) Swap(i, j int) {
a := *h
a[i], a[j] = a[j], a[i]
}
func (h *hp) Push(x any) {
*h = append(*h, x.(pair))
}
func (h *hp) Pop() any {
a := *h
v := a[len(a)-1]
*h = a[:len(a)-1]
return v
}
C++版本代码
class Solution {
public:
int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold) {
vector<vector<int>> w(n, vector<int>(n, INT_MAX >> 1));
for (int i = 0; i < edges.size(); i++) {
int x = edges[i][0], y = edges[i][1], v = edges[i][2];
w[x][y] = v, w[y][x] = v;
}
auto f = move(w);
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
}
}
}
int minCnt = n - 1, ans = 0;
for (int i = 0; i < n; i++) {
int cnt = 0;
for (int j = 0; j < n; j++) {
if (i != j && f[i][j] <= distanceThreshold) {
cnt++;
}
}
if (cnt <= minCnt) {
minCnt = cnt;
ans = i;
}
}
return ans;
}
};
static int fast_io = [](){
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
return 0;
}();