//打赏的js文件

拆分数字

拆分数字

题目

题目描述

小明同学探索到一个古老的数学遗迹,在遗迹的深处发现了若干到道神秘的谜题。谜题中给出了整数 \(n\)\(k\),并有如下提示:“在这个神秘的地方,存在着一类特殊的数字,它们的形式为 \(3^m\)\(m\) 是非负整数)。现在需要判断能否通过恰好 \(k\) 个这样的特殊数字相加,得到整数 \(n\)

换言之,是否存在一个非负整数序列 \(\{a_k\}\),使得 \(n=3^{a_1}+3^{a_2}+...+3^{a_k}\)

不出意外的,小明同学又把这个任务交给你了。

输入格式(文件名:split.in)

输入的第一行包含一个正整数 \(T\),表示谜题的个数。

接下来 \(T\) 行,每行两个整数 \(n,k\),表示一道谜题中的信息。

输出格式(文件名:split.out)

输出共 \(T\) 行。对于每一道谜题,如果可以则输出 Yes ,否则输出 No

样例数据

【样例 \(1\) 输入】

4
5 3
17 2
163 79
1000000000 1000000000

【样例 \(1\) 输出】

Yes
No
Yes
Yes

【样例 \(1\) 解释】
对于第一个测试案例,\(5=3^1+3^0+3^0\),因此满足了相关条件。

对于第二个测试案例,没有非负整数序列 \(a_1,a_2\) 使得 \(17=3^{a_1}+3^{a_2}\),因此不满足有关条件。

数据范围

对于 \(30\%\) 的数据,保证 \(n\le10,k\le5\)
对于另 \(30\%\) 的数据,保证 \(n\le1000,k\le2\)
对于 \(100\%\) 的数据,保证 \(1\le k\le10^9,1\le T\le10^5\)

题解

我们发现 \(3\) 进制下各个位数之和是 \(k\) 的最小值。所以我们可以先用 \(ans\) 统计出数量。我们在后面也可以发现 \(3^{m+1}=3\times3^m\),所以 \(ans\le k\) 并且 \(ans\)\(k\) 奇偶性一样就输出 Yes,否则输出 No

代码

#include <bits/stdc++.h>
#define int long long

using namespace std;

int t, n, k, ans;

signed main() {
  freopen("split.in", "r", stdin);
  freopen("split.out", "w", stdout);
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  for (cin >> t; t--; ans = 0) {
    cin >> n >> k;
    for (; n; ans += n % 3, n /= 3) {
    }
    cout << (k >= ans && abs(ans - k) % 2 == 0 ? "Yes\n" : "No\n");
  }
  return 0;
}
posted @ 2024-09-23 14:09  小熊涛涛  阅读(42)  评论(0编辑  收藏  举报