HDU1061 Rightmost Digit(二分求幂,快速幂,尾数规律)c++

Rightmost Digit

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 72230 Accepted Submission(s): 26695

Problem Description
Given a positive integer N, you should output the most right digit of N^N.

Input
The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case contains a single positive integer N(1<=N<=1,000,000,000).

Output
For each test case, you should output the rightmost digit of N^N.

Sample Input
2
3
4

Sample Output
7
6

Hint
In the first case, 3 * 3 * 3 = 27, so the rightmost digit is 7.
In the second case, 4 * 4 * 4 * 4 = 256, so the rightmost digit is 6.

问题连接

问题描述

给出n,求n的n次方最右侧的数。

问题分析

显然,个位只与它的个位以及指数有关,故像找128的128次方的个位数相当于找8的128方的个位数,而且每次大于9后都可以通过求余找到个位。
方法:
二分求幂:我的理解是指数为奇数时,ans乘一次底数,偶数时不处理。再底数求平方,如此循环,直到指数为0.像1* 2^7= 2* 2 ^6 = 2* 4 ^3=8* 4 ^2=8* 16 ^1=128;
快速幂:感觉道理和二分求幂相似,不过是把指数从十进制变成了二进制,再利用位运算(&和>>)进行处理。
两种方法都可以大幅度减少相乘的次数。
还有一种方法是找规律,如个位为0,1,5,6的数不管指数为多少,所得的数的个位也是0,1,5,6。
其它数也有相似的规律。如2的规律是:2,4,8,6,2,4,8,6,…用数组记录规律,对指数求余,即可。

c++程序如下

二分求幂

#include<iostream>
using namespace std;
int two_point(int,long long);
int main()
{
	long long n;
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n;
		cout << two_point(n%10,n) << endl;
	}
	return 0;
}
int two_point(int x, long long n)//x^n求尾数版
{
	int ans=1;
	while (n)//等于0时跳出
	{
		if (n % 2 == 1)
		{
			ans *= x;
			ans %= 10;
		}
		x = x*x;
		x %= 10;
		n /= 2;
	}
	return ans;
}

快速幂

#include<iostream>
using namespace std;
int fast(int, long long);
int main()
{
	long long n;
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n;
		cout << fast(n % 10, n) << endl;
	}
	return 0;
}
int fast(int x, long long n)//x^n求尾数版
{
	int ans = 1;
	while (n>0)
	{
		if (n & 1 == 1)
		{
			ans *= x;
			ans %= 10;
		}
		x *= x;//指数少一半
		x %= 10;//避免int溢出
		n >>= 1;
	}
	return ans;
}

尾数规律

#include<iostream>
using namespace std;
int main()
{
	long long n;
	int x,t,num[10][4] = { { 0 }, { 1 }, { 6, 2, 4, 8 }, { 1, 3, 9, 7 }, { 6, 4 }, { 5 }, { 6 },
	{ 1, 7, 9, 3 }, { 6, 8, 4, 2 }, { 1, 9 } };
	cin >> t;
	while (t--)
	{
		cin >> n;
		x = n % 10;
		switch (x)
		{
		case 0:
		case 1:
		case 5:
		case 6:cout << x << endl; break;
		case 2:
		case 3:
		case 7:
		case 8:n %= 4; cout << num[x][n] << endl; break;
		case 4:
		case 9:n %= 2; cout << num[x][n] << endl; break;
		}
	}
	return 0;
}

ACC

猜你喜欢

转载自blog.csdn.net/DouglasConnor/article/details/85110283