给定一个 A 进制下的分数 a/b, 小蓝想把它化为 B 进制下的小数 c。 现在他想知道这个小数是不是一个有限小数。
输入共一行,包含四个数 a, b, A, B,表示该分数和两种进制。 其中 A, B 使用十进制表示, a, b 中大于 9 的数字使用大写字母表示, A 表示 10,B 表示 11,以此类推。
输出一行,包含一个字符串。 如果该小数是一个有限小数,则输出 "Yes"; 否则输出 "No"(不包含引号)。
10 11 10 11
Yes
对于 20% 的评测用例,A = B = 10。 对于所有评测用例,0 <= a < b <= 10^9, 2 <= A, B <= 36(数为十进制)。
本题需要用到数字逻辑的小数的进制转换知识,举个例子:将0.3转换成2进制小数
0.3 * 2 = 0.6———————0
0.6 * 2 = 1.2———————1
0.2 * 2 = 0.4———————0
0.4 * 2 = 0. ———————0
0.8 * 2 = 1.6———————1
0.6 * 2 = 1.2———————1
0.2 * 2 = 0.4———————0
0.4 * 2 = 0.8———————0
取8位小数的话0.3 = 0.01001100
转换成B进制只需要将上面的2换成B即可
这样,将 a/b 转换成B进制只需
令 Y=a/b
将 Y*B^k ,k按保留的位数取
所以这道题我们只需将 k 取得很大,再看最后Y是否为零即可判断出它是否能被b整除,
这里 a*B^k 可能会很大,所以我们呢可以一边乘一边对 b 取模
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- using namespace std;
- typedef long long LL;
- const int N = 1e7 + 5;
- LL a, b, A, B;
- string sa, sb;
-
- LL F(string x) {
- LL ret = 0;
- int len = x.length();
- LL t = 1;
- for (int i = len - 1; i >= 0; i--) {
- if (x[i] >= '0' && x[i] <= '9') {
- ret += (x[i] - '0') * t;
- }
- else {
- ret += (x[i] - 'A' + 10) * t;
- }
- t *= A;
- }
- return ret;
- }
-
- int main() {
- cin >> sa >> sb >> A >> B;
- a = F(sa);
- b = F(sb);
- a %= b;
- for (int i = 1; i <= N&&a; i++) {
- a *= B;
- a %= b;
- }
- if (a == 0) {
- cout << "Yes" << endl;
- }
- else {
- cout << "No" << endl;
- }
- return 0;
- }