代码借鉴SCAU-OJ(感谢!!)
题目:1076 K尾相等数
时间限制:500MS 内存限制:65536K
提交次数:251 通过次数:80
题型: 编程题 语言: G++;GCC
Description
从键盘输入一个自然数K(99999999>K>1),若存在自然数M和N(M>N),使得K的M次方和K的N次方均大于或等于1000,
且它们的未尾三位数相等,则称M和N是一对“K尾相等数”。请编程序,输出K尾相等数中M+N最小值。
输入样例
2
输出样例
120
思路:
核心就是m是要>n的,所以就要先确定一个,然后再确定另外一个的,然后用了一个a数组,下标是不同的后三位,然后存放的值是m次方后这个数的后三位是这个下标,t用来暂时的存放k
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
int n,m,a[1005],i,j,k,t;//n和m就是题目中说到的次方了,然后a数组的下标其实是t%1000的余数,
//值就是当t的后三位数是这个下标的话此时对应的次方数了
memset(a,0,sizeof(a));
scanf("%d",&k);
if(k>=1000)//当已经是大于等于1000的话说明m已经满足了
{
t=k;
m=1;
}//思路就是先确定一个次方是满足的m,之后再搞另外一个次方即可了
else//如果输入的数小于1000的话就继续乘,在乘的同时就不断的递增m
{
t=k;
m=1;
while(t<1000)
{
t*=k;
m++;
}
}
while(1)
{
t%=1000;//把t设置为t的后三位数
if(a[t]>0)break;//这里才是结束的条件,由于开始的时候初始化a数组的每个值都是0了,
// 而这个判断大于0就退出是因为如果a[t]大于0的话说明我们已经赋值过了,访问过了,也就是说之前我们得到了一个k的次方值等于这个下标t的,而这个次方被存放在了这个a[t]内,然后之后遍历又一次访问到了a[t],也就是说此时的次方和之前访问过了之后存放在c[t]的次方是满足题目条件的,所以break出来就吧此时的次方也就是m和之前已经存放的次方a[t]相加就是最小的了
a[t]=m++;//把a数组的下标设置成是t的后三个余数的,然后数组存的值就是此时t=k^m,吧这个m存放在这个数组里面
t*=k;//不断连乘直到再次访问相同的后三个数
}
printf("%d",a[t]+m);
return 0;
}