一、Problem
如果一個數的十進制各位能夠被分爲兩個集合,並且這兩個集合裏的數的和相等,我就認爲是吉祥數。而吉祥數的個數則意味着我們的默契度。現在給你兩個數 ,你能告訴我 中有幾個數是吉祥數嗎?
輸入
輸入兩個數l和r。
輸出
輸出 中吉祥數的個數。
11 20
1
990 5930
1158
二、Solution
方法一:BE
- BE 得到每一個 的每一個子集 A,那麼 A 肯定存在一個補集 B。
- 我們將這兩個集合的累加和求出來,記錄到 sum1 和 sum2 中。
- 如果 sum1 = sum2,返回 true 即可…
留下 30/100 超時的淚水…😂
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static class Solution {
boolean check(int n) {
char[] s = (n + "").toCharArray();
int N = s.length, tot = 1 << N;
for (int i = 0; i < tot; i++) {
int s1 = 0, s2 = 0;
for (int j = 0; j < N; j++) {
if ((i & (1 << j)) > 0) s1 += s[j] - '0';
else s2 += s[j] - '0';
}
if (s1 == s2)
return true;
}
return false;
}
void init() {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int l = sc.nextInt(), r = sc.nextInt(), res = 0;
for (int i = l; i <= r; i++) {
if (check(i))
res++;
}
System.out.println(res);
}
}
public static void main(String[] args) throws IOException {
Solution s = new Solution();
s.init();
}
}
複雜度分析
- 時間複雜度:,比預算要快…
- 空間複雜度:,
方法二:01 dp
- 定義狀態:
- 表示總和爲 的狀態可達。
- 思考狀態轉移方程:
- 表示兩個狀態其一到達 就說明 可達。
- 思考初始化:
- ,表示總和 0 的狀態不需要選數字就能達到。
- 思考輸出:
再次留下超時的淚水…🤣
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static class Solution {
void init() {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int l = sc.nextInt(), r = sc.nextInt(), res = 0;
for (int k = l; k <= r; k++) {
int sum = 0, t = k;
List<Integer> all = new ArrayList<>();
while (t > 0) {
int bit = t % 10;
all.add(bit);
sum += bit;
t /= 10;
}
if (sum % 2 != 0)
continue;
boolean[] dp = new boolean[sum+1];
dp[0] = true;
sum >>= 1;
for (int i = 0; i < all.size(); i++) {
for (int j = sum; j >= all.get(i); j--)
dp[j] = dp[j] | dp[j-all.get(i)];
}
if (dp[sum]) res++;
}
System.out.println(res);
}
}
public static void main(String[] args) throws IOException {
Solution s = new Solution();
s.init();
}
}
複雜度分析
- 時間複雜度:
- 空間複雜度:,
目前沒有找到可 ac 的思路,望仙人指路…