[题解]UVA11549 Calculator Conundrum

前言:首先感谢 @ Kisaragi_77 大佬为我提供的思路。

思路

这是我们今天模拟赛的一道题,拿到这道题后,一点思路都没有,在老师的指导下,想到了用 map ,但是并没有写出来。

考试后,我看了一下题解,发现 @ Kisaragi_77 大佬的思路非常清晰。

具体做法呢,就是用一个 set 来实现。

不会用 set 来看着这里

先写一个死循环,再循环中判断新算出来的这个数是否在 set 中出现过,如果出现过,说明有一个循环,不会再出现新的值了,就输出 set 最后一个值。

我来举一个例子吧!

n=1,k=6 时,计算器会依次显示 6,3,9,8,6,3..., 这个时候你会发现在第二个 6,3 开始后都在重复之前的 6,3,9,8

事实证明,只要出现了循环就可以结束了

但,为什么是输出最后一个值呢?

最主要的原因便是: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 国际」许可协议进行许可。

posted @   WBIKPS  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示