[题解]UVA11549 Calculator Conundrum
前言:首先感谢 @ Kisaragi_77 大佬为我提供的思路。
思路
这是我们今天模拟赛的一道题,拿到这道题后,一点思路都没有,在老师的指导下,想到了用 map
,但是并没有写出来。
考试后,我看了一下题解,发现 @ Kisaragi_77 大佬的思路非常清晰。
具体做法呢,就是用一个 set
来实现。
不会用 set
来看着这里
先写一个死循环,再循环中判断新算出来的这个数是否在 set
中出现过,如果出现过,说明有一个循环,不会再出现新的值了,就输出 set
最后一个值。
我来举一个例子吧!
当 时,计算器会依次显示 这个时候你会发现在第二个 开始后都在重复之前的
事实证明,只要出现了循环就可以结束了
但,为什么是输出最后一个值呢?
最主要的原因便是:set
在存储和删除中,都是会保序的,所以 set
中储存过的数中最后一个数必定时最大的。
Code
#include <bits/stdc++.h>
#define int long long//防止有爆 int 范围,这个方法需要把值函数前面的 int 改成 signed
using namespace std;
int T;//组数
int n,k;//见题目
int f(int x){//用来求一个数的前 n 位的函数
int p = pow(10,n);//前 n 位便有至少有 pow(10,n)便于我们对返回前 n 为的值
while (x >= p) x /= 10;//如果当前的值大于等于 n 位数的最小值便要除以 2
return x;//最后返回 x
}
signed main(){
cin >> T;
while (T--){
set<int> s;//定义一个 set
cin >> n >> k;//输入 n,k
s.insert(f(k));//将 f(k) 插入到 s 中,因为题目中说了他在计算器上输入了一个 k,并且防止 k 大于 n 位数,所以我们要向 s 中插入 f(k)
while (1){//先写一个死循环
int t = f(k * k);//算出新的数,并对其使用 f 函数
if (s.count(t)){//如果先算出的数在 s 中出现过了,那么就说明已经出现了循环,不可能再出新的数了
printf("%lld\n",*(--s.end()));//输出最后一个数
break;//结束循环
}
else s.insert(t);//否则将新算出的数插入到 s 中
k = t;//将 k 更新成为新数
}
}
return 0;
}
作者:WaterSun
出处:https://www.cnblogs.com/WaterSun/p/18270908
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】