例题19 计算器谜题(Uva 11549) (Floyd 判圈算法)

有一个计算器只能显示 n n n位数字,输入一个整数k,然后把它反复平方直到溢出为止,然后把溢出数字最高位n作为下一次的k如此反复
思路:显然存在循环节.为什么.假设第一次溢出的数字是k1,反复平方后得到k2.如果不存在循环节, k 1 ! = k 2 k1!=k2 k1!=k2.假设进行了11次上述过程,得到了11个不同的数字,而由于最高位的数字是0~9,抽屉原理,至少有一个数字出现了两次,那么它就是循环节了.
怎么判断循环节比较快一点呢.书上提供了两种思路,开set,或者Floyd判圈.
我采用的是第二种思路.判圈就是类似于链表的快慢指针,一个走两步一个走一步,走两步的一定能追上走一步的,如果存在一个循环节.

/*
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+2;
const int INF = 1e9+7;
typedef pair<int,int> pii;
int cnt[15];
ll get(ll n,ll k){
	if(k==0) return k;
	memset(cnt,0,sizeof(cnt));
	ll pow = k*k;
	int len = 0;
	while(pow){
		cnt[len++] = pow%10;
		pow/=10;
	}
	//注意位数少于n位的情况. 
	if(len<n) n = len;
	ll ans = 0;
	for(int i=0;i<n;i++){
		ans = ans*10 + cnt[--len];
	}
	return ans;
}
int main(){
//	freopen("1.txt","r",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int T;cin>>T;
	while(T--){
		ll n,k;
		cin>>n>>k;
		ll ans = k;
		ll k1 = k,k2=k;
		do{
			k1 = get(n,k1);
			ans = max(ans,k1);
			k2 = get(n,k2);ans=max(ans,k2);
			k2 = get(n,k2);ans = max(ans,k2);
		} while(k1!=k2);
		cout<<ans<<"\n";
	}
return 0;}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

minato_yukina

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值