【TSOJ课程】23 1247 邮箱密码

课程29_23 1247 邮箱密码


题目:

题目描述:

小婷有一个 E-Mail 邮箱的密码是 n 位长长正整数(n 大于 3),但由于有一段日子不使用此邮箱,她忘记了密码。小婷的生日是 8 月 1 日,她妈妈的生日是 9 月 1 日,她特别喜欢把同时是 81 和 91 的倍数用做密码。此外,小婷还记得这个密码的百位数是 1。请设计一个程序找回这个密码。密码必须是唯一的。

输入描述:

多组输入,占一行,输入一个 n 位数的正整数

输出描述:

占一行,如果满足条件则输出密码,否则输出 wrong。

样例输入:

18923
200000

样例输出:

22113
wrong


解析:

题目里说了,密码同时是81和91的倍数,意思就是说密码是81和91的公倍数。而我们都知道,a和b的所有公倍数,其实就是a和b的最小公倍数的整数倍。而81和91的最小公倍数是7371,也就是说,密码肯定是7371的整数倍。

那我们直接暴力搜索就可以了。题目说密码是唯一的,如果出现了两个满足条件的数字,就说明密码错误,输出wrong。

所以我们准备2个函数:

int f(int n)
{
	return n%1000/100;
}

这个函数是用来求百位上是什么数字的。比如f(2501)=5。

int ilen(int n)
{
	return log10(n)+1;
}

这个函数是用来求数字的位数的,比如f(1919191919)=10。

注意看完这部分以后别急着走,下面还有一种更简单的方法。


解题:

穷举7371的所有倍数即可。

参考代码:

// TSOJ-1247 邮箱密码
#include <iostream>
#include <cmath>
#include <string>
using namespace std;

int f(int n)
{
	return n%1000/100;
}

int ilen(int n)
{
	return log10(n)+1;
}

int main()
{
	string inp;
	int sl,res,temp,iltemp;
	while(cin>>inp)
	{
		sl = inp.length();
		res = 0;
		for(int i=0;i<291343;i++)
		{
			temp = i*7371;
			iltemp = ilen(temp);
			if(iltemp>sl)
				break;
			if(iltemp==sl){
				if(f(temp)==1){
					if(res==0)
						res = i*7371;
					else{
						res = -1;
						break;
					}
				}
			}
		}
		if(res!=0 && res!=-1){
			cout<<res<<endl;
		}else{
			cout<<"wrong"<<endl;
		}
	}
}
 

比较厉害的解法

在测试代码的过程中,我们会发现,如果我们输入的位数比较大,输出的基本上都是wrong。这个也比较好理解,毕竟位数越多,在这个位数范围里的7371的整数倍自然就多,那么出现多个符合条件(百位是1)的概率自然也大。

那我们是否可以证明这一点呢?

当然可以

首先,22113是7371的整数,同时它的百位是1

然后我们构造出两个数字:14742000(7371的2000倍)、22113000(7371的3000倍)。

我们发现这两个数字的百位都是0。很明显,如果一个数字的百位是0,另一个数字的百位是1,这两个数字的和的百位也一定是1

既然如此,那就意味着有两个8位数(同时也是7371的整数倍)的百位都是1。题目里说了,密码是唯一的,那说明8位数里没有密码

再往下想,我们会发现:1474200022113000还可以乘10,变成147420000221130000,他们的百位仍然是0!那说明9位数里还是没有密码因为不唯一)。

这个结论可以无限的类推下去,也就是说:8位以及更高的情况,都是wrong

接下来,我们枚举1~7位的情况:

位数结果
1wrong
2wrong
3wrong
4wrong
522113
6wrong
7wrong

所以答案就呼之欲出了:

当输入位数为5的时候,输出22113,其他情况输出wrong

那么超简单代码如下:

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string inp;
	while(cin>>inp)
	{
		if(inp.length() == 5)
			cout<<"22113"<<endl;
		else
			cout<<"wrong"<<endl;
	}
	return 0;
}
  • 13
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值