【PAT(Advanced Level) Practice】1010 Radix(二分)

2023-05-16

链接:

https://pintia.cn/problem-sets/994805342720868352/problems/994805507225665536

题意:

有两个数 N 1 , N 2 N1,N2 N1N2,已知其中一个数的基数 r a d i x radix radix,问若要使 N 1 = = N 2 N1 == N2 N1==N2,那么另一个数的基数是多少。

思路:

假设:已知 N 1 N1 N1 的基数

我刚开始的思路是将 N 1 N1 N1 先转成 10 10 10 进制,然后再找到 N 2 N2 N2 中每位的数字中最大的那个数 r r r(因为 N 2 N2 N2 的进制一定 ≥ r + 1 \ge r+1 r+1),然后从 r + 1 r+1 r+1 开始并且每步 + 1 +1 +1 顺序去找 N 2 N2 N2 的进制(因为当数 N 2 N2 N2 给定时,它的进制越大, N 2 N2 N2 实际上就越大),对于每一个 r r r 比较在当前 r r r 进制下 N 2 10 进 制 N2_{10进制} N210 是否 = = = N 1 10 进 制 N1_{10进制} N110,如果 = = = 就找到了,直接输出。如果 N 2 10 进 制 > N 1 10 进 制 N2_{10进制} > N1_{10进制} N210>N110 则说明等式不可能成立,输出Impossible。(注释掉的代码)

这样做最后有一个测试点超时,我第一反应加上了快速幂,依旧超时。我测试了几次后发现是找 N 2 N2 N2 进制的 while 循环超时了,但是我没想到二分,直到百度之后,我才知道要用二分大法(被自己蠢哭了)。

正解: 上述思路不变,将找 N 2 N2 N2 的进制数 从 顺序查找 优化成 二分查找。二分的下界就是 r + 1 r+1 r+1, 上界设成 N 1 N1 N1 N 2 N2 N2 的基数 不可能大于已给 N 1 N1 N1,因为 如果 N 2 N2 N2 的基数 > N 1 > N1 >N1,那么只要 N 2 N2 N2 不是 0 0 0 N 2 N2 N2 就一定会大于 N 1 N1 N1,显然不合理)。
但是这样又出现了一个问题: N 2 N2 N2 比较大,在二分尝试比较大的基数的时候,会超 long long 的范围,产生溢出,使得判断条件不成立。(这也是百度知道的,当时已经不动脑了!!!)
解决溢出: 首先可以确定给出的已知数据 N 1 , N 2 N1,N2 N1,N2 最多 10 10 10 位数字,每位最大是 z z z,它们是不会溢出的。那么如果溢出(出现负值),就一定是基数上溢,基数取得过大了。因此多加一个判断即可(N2_10 < 0 || N2_10 > N1_10)。

在这里插入图片描述

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

LL qpow(LL x, LL n) {
	LL res = 1;
	while(n) {
		if(n&1) res *= x;
		x *= x;
		n >>= 1;
	}
	return res;
}

LL n2ten(string s, LL radix) {
	// cout<<"s : "<<s<<endl;
	LL res = 0;
	for (int i = s.size()-1; i >= 0; --i) {
		char now = s[i];
		char tmp = (now >= '0' && now <= '9')?'0':'a'-10;
		// cout<<"now-tmp : "<<now-tmp<<endl;
		// cout<<"pow(radix, s.size()-1-i) : "<<pow(radix, s.size()-1-i)<<endl;
		res += (now-tmp)*qpow(radix, s.size()-1-i);
	}
	return res;
}

void solve(string N1, string N2, LL radix) {
	LL N1_10 = n2ten(N1, radix);
	// cout<<"N1_10 : "<<N1_10<<endl;
	char maxE = *max_element(N2.begin(), N2.end());
	char tmp = (maxE >= '0' && maxE <= '9')?'0':'a'-10;
	LL r = maxE - tmp + 1;
	// cout<<"r : "<<r<<endl;
	// while(1) { // TLE
	// 	LL N2_10 = n2ten(N2, r);
	// 	// cout<<"N2_10 : "<<N2_10<<endl;
	// 	if(N2_10 > N1_10) {
	// 		cout<<"Impossible"<<endl;
	// 		return ;
	// 	}
	// 	if(N2_10 == N1_10) {
	// 		cout<<r<<endl;
	// 		return ;
	// 	}
	// 	r++;
	// }
	LL s = r, t = max(s, N1_10); 
	// N2 的基数 不可能大于已给 N1,因为 如果 N2 的基数 > N1,那么只要 N2 不是 0,N2 就一定大于 N1,显然不合理
	while(s <= t) {
		LL m = (s+t) >> 1;
		LL N2_10 = n2ten(N2, m);
		if(N2_10 == N1_10) {
			cout<<m<<endl;
			return ;
		}
		if(N2_10 < 0 || N2_10 > N1_10) t = m-1; 
		// 溢出,给出的已知数据(N1,N2)是不会溢出的,那么只要是取值为负的,全部是上溢,基数取得过大了。
		else s = m+1;
	}
	cout<<"Impossible"<<endl;
}

int main(int argc, char const *argv[])
{
	string N1, N2;
	LL tag, radix;
	cin>>N1>>N2>>tag>>radix;
	if(tag == 2) {
		swap(N1, N2);
	}
	solve(N1, N2, radix);
	return 0;
}

参考链接

  1. 1010. Radix (25)-PAT甲级真题(二分法)
  2. 1010 Radix (25)(25 分)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【PAT(Advanced Level) Practice】1010 Radix(二分) 的相关文章

  • error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2

    错误原因 xff1a qtmain lib qtmain win obj error LNK2038 检测到 ITERATOR DEBUG LEVEL 的不匹配项 值 0 不匹配值 2 xxxx obj 中 值 0 不匹配值 2表示当前链接
  • Do Lots of Deliberate Practice 22

    Do Lots of Deliberate Practice Deliberate practice is not simply performing a task If you ask yourself Why am I performi
  • 检测到"_ITERATOR_DEBUG_LEVEL"的不匹配项

    最近在项目中遇到了问题 xff0c 编译器提示 检测到 34 ITERATOR DEBUG LEVEL 34 的不匹配项 xff0c 上网查找后发现是编译Release版本用到了DEBUG库的原因 xff0c 其中也提供了在预编译中加入 3
  • 肿瘤诊断(PAT)

    题目链接 https www patest cn contests gplt L3 004 一道很裸的bfs 一开始以为会超时 抱着试一试的心态交了一发竟然过了 include
  • PAT

    1045 快速排序 25分 著名的快速排序算法里有一个经典的划分过程 我们通常采用某种方法取一个元素作为主元 通过交换 把比主元小的元素放到它的左边 比主元大的元素放到它的右边 给定划分后的 N 个互不相同的正整数的排列 请问有多少个元素可
  • 【PAT】1033 旧键盘打字 (20 分)

    1033 旧键盘打字 20 分 旧键盘上坏了几个键 于是在敲一段文字的时候 对应的字符就不会出现 现在给出应该输入的一段文字 以及坏掉的那些键 打出的结果文字会是怎样 输入格式 输入在 2 行中分别给出坏掉的那些键 以及应该输入的文字 其中
  • L1-095 分寝室PTA

    学校新建了宿舍楼 共有 n 间寝室 等待分配的学生中 有女生 n0 位 男生 n1 位 所有待分配的学生都必须分到一间寝室 所有的寝室都要分出去 最后不能有寝室留空 现请你写程序完成寝室的自动分配 分配规则如下 男女生不能混住 不允许单人住
  • 1004 成绩排名 (20 分) Java写法 读入n名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。

    读入 n gt 0 名学生的姓名 学号 成绩 分别输出成绩最高和成绩最低学生的姓名和学号 输入格式 每个测试输入包含 1 个测试用例 格式为 第 1 行 正整数 n 第 2 行 第 1 个学生的姓名 学号 成绩 第 3 行 第 2 个学生的
  • 分支-20. 计算符号函数的值(10)

    对于任一整数n 符号函数sign n 的定义如下 请编写程序计算该函数对任一输入整数的值 输入格式 输入在一行中给出整数n 输出格式 在一行中按照格式 sign n 函数值 输出该整数n对应的函数值 输入样例 1 10 输出样例 1 sig
  • 2020年十二月ccf-csp认证总结(内附个人题解)

    吐槽一下这个在线评测功能 平均四十分钟才能看到提交结果 本次成绩为100 100 0 30 20 最后两道题都是骗的分 提醒自己附代码的神奇图片 希望寒假有时间把没做出来的题目也再做一遍 csp官网更新出题目后 有路过的可以提醒我把题目加上
  • PAT 1103 Integer Factorization

    题目的意思是给定n k p 求是否存在k个正整数 每个数的p次幂相加的结果等于n 有 输出k个数相加的结果最大的那个 如果有多个 输出序列从大到小排最大的那个 从左往右比较 若 i lt l a i
  • Pat刷题真题乙级(4)

    标题 前言 Pat乙级1013 组个最小数 Pat乙级1014 科学计数法 Pat乙级1017 打印沙漏 Pat乙级1018 人口普查 Pat乙级1019 旧键盘 前言 这个周末花了两天才写了五道题 嘿嘿 康康吧 Pat乙级1013 组个最
  • PAT : PAT (Basic Level) Practice(中文)答案(1001 ~ 1095)(纯C编写)

    题目集地址 报名了12月的PAT B 先试试水 已完成 2018 10 22 2018 11 14 更新 2018 12 09 PAT乙级考试100分 考试代码已更新 冬天坐火车跑去考试冻懵了 来年对战PAT甲级考试 目录 目录 题目集地址
  • PAT乙级题解—— 1071 小赌怡情 (15分)

    常言道 小赌怡情 这是一个很简单的小游戏 首先由计算机给出第一个整数 然后玩家下注赌第二个整数将会比第一个数大还是小 玩家下注 t 个筹码后 计算机给出第二个数 若玩家猜对了 则系统奖励玩家 t 个筹码 否则扣除玩家 t 个筹码 注意 玩家
  • 1032. 挖掘机技术哪家强(20)

    为了用事实说明挖掘机技术到底哪家强 PAT组织了一场挖掘机技能大赛 现请你根据比赛结果统计出技术最强的那个学校 输入格式 输入在第1行给出不超过105的正整数N 即参赛人数 随后N行 每行给出一位参赛者的信息和成绩 包括其所代表的学校的编号
  • 1012.数字分类- PAT乙级真题

    给定一系列正整数 请按要求对数字进行分类 并输出以下 5 个数字 A 1 能被 5 整除的数字中所有偶数的和 A 2 将被 5 除后余 1 的数字按给出顺序进行交错求和 A3 被 5 除后余 2 的数字的个数 A 4 被 5 除后余 3 的
  • 1007. 素数对猜想 (20)

    让我们定义 dn 为 dn pn 1 pn 其中 pi 是第i个素数 显然有 d1 1 且对于n gt 1有 dn 是偶数 素数对 猜想 认为 存在无穷多对相邻且差为2的素数 现给定任意正整数N lt 105 请计算不超过N的满足猜想的素数
  • 1055. 集体照 (25) PAT乙级真题

    1055 集体照 25 拍集体照时队形很重要 这里对给定的N个人K排的队形设计排队规则如下 每排人数为N K 向下取整 多出来的人全部站在最后一排 后排所有人的个子都不比前排任何人矮 每排中最高者站中间 中间位置为m 2 1 其中m为该排人
  • 分支-11. 计算工资(15)

    某公司员工的工资计算方法如下 一周内工作时间不超过40小时 按正常工作时间计酬 超出40小时的工作时间部分 按正常工作时间报酬的1 5倍计酬 员工按进公司时间分为新职工和老职工 进公司不少于5年的员工为老职工 5年以下的为新职工 新职工的正
  • 【PAT】B1032 挖掘机技术哪家强 (20 分)_C语言实现

    1 挖掘机技术哪家强 20 分 为了用事实说明挖掘机技术到底哪家强 P A T PAT PAT 组织了一场挖掘机技能大赛 现请你根据比赛结果统计出技术最强的那个学校 输入格式 输入在第 1

随机推荐