有限小数,进制转换,思维

Contest (nefu.edu.cn)

Problem:G
Time Limit:1000ms
Memory Limit:65535K

Description

给定一个 A 进制下的分数 a/b,
小蓝想把它化为 B 进制下的小数 c。
现在他想知道这个小数是不是一个有限小数。

Input

输入共一行,包含四个数 a, b, A, B,表示该分数和两种进制。
其中 A, B 使用十进制表示,
a, b 中大于 9 的数字使用大写字母表示,
A 表示 10,B 表示 11,以此类推。

Output

输出一行,包含一个字符串。
如果该小数是一个有限小数,则输出 "Yes";
否则输出 "No"(不包含引号)。

Sample Input

10 11 10 11

Sample Output

Yes

Hint

对于 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<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
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;
}

posted @ 2023-10-22 16:53  Landnig_on_Mars  阅读(10)  评论(0编辑  收藏  举报  来源