http://poj.grids.cn/practice/4010/
/*
*********************************************************************************
4010 - 2011
时间限制:
1000ms
内存限制:
65536kB
描述
已知长度最大为200位的正整数n,请求出2011^n的后四位。
输入
第一行为一个正整数k,代表有k组数据,k<=200接下来的k行,
每行都有一个正整数n,n的位数<=200
输出
每一个n的结果为一个整数占一行,若不足4位,去除高位多余的0
样例输入
3
5
28
792
样例输出
1051
81
5521
********************************************************************************* */
/* *********************************************************************************
解题思路:
abcd
abcd
.......
abcd
abcd
abcd
*abcd
-----------
....ABCD
假设一个数(abcd)^n的结果的后四位是:ABCD,那么可以得到:
D = ( d^n )%10 进位t1 = (d^n) / 10
C = ( n*c*(d^(n-1)) + t1 ) % 10 进位t2 = ( n*c*d^(n-1) + t1 ) / 10
B = ( n*b*(d^(n-1)) + (n*(n-1)/2)*(c^2)*(d^(n-1)) + t2 ) % 10 进位t3
A = ( n*a*(d^(n-1)) + (n*(n-1)/2)*b*c*(d^(n-2)) + (n*(n-1)*(n-2)/6)*(c^3)*(d^(n-3)) + t3 )%10
其中:(n*(n-1)/2)表示组合数Cn2, (n*(n-1)*(n-2)/6)表示组合数Cn3。
由于a = 2, b = 0, c = 1, d = 1已知,那么带入可得:
D = 1, t1 = 0
C = n%10, t2= n / 10
B = ( n*(n-1)/2 + t2 ) % 10, t3 = ( n*(n-1)/2 + t2 ) / 10
A = ( 2*n + n*(n-1)*(n-2)/6 + t3) % 10
带入样例输入可知正确性。
最后的难度在于n太大了,有200位,我们可以考虑是不是存在一个数t,使得:
(2011)^t 的末四位仍然是2011??
那么就是解方程令D = 1, C = 1, B = 0, A = 2求出t>1的最小正整数,我们尝试t = 1001,满足要求。
再尝试t = 101不满足。再尝试501满足。所以就可以对所有的n,我们取末三位再模除500。
注意,t = 500时候,(2011)^t的末四位就是0001。所以(2011)^(t+1)的末四位就是2011.
********************************************************************************* */
#include < iostream >
#include < cmath >
#include < cctype >
#include < string >
#include < map >
#include < set >
#include < vector >
#include < algorithm >
#include < list >
// #include <stdlib.h>
// #include <iomanip>
using namespace std;
int main()
{
int k, n, len, ans;
int a[ 4 ], t2, t3;
string str;
cin >> k;
for ( int i = 0 ; i < k; i ++ )
{
cin >> str;
len = str.length();
n = 0 ;
for ( int j = len - 1 , t = 1 ; j >= 0 && j >= len - 3 ; j -- )
{
n += (str[j] - ' 0 ' ) * t;
t *= 10 ;
}
n %= 500 ;
a[ 0 ] = 1 ;
a[ 1 ] = n % 10 ;
t2 = n / 10 ;
a[ 2 ] = n * (n - 1 ) / 2 + t2;
t3 = a[ 2 ] / 10 ;
a[ 2 ] %= 10 ;
a[ 3 ] = ( 2 * n + n * (n - 1 ) * (n - 2 ) / 6 + t3) % 10 ;
ans = a[ 0 ] + a[ 1 ] * 10 + a[ 2 ] * 100 + a[ 3 ] * 1000 ;
cout << ans << endl;
}
return 0 ;
}
4010 - 2011
时间限制:
1000ms
内存限制:
65536kB
描述
已知长度最大为200位的正整数n,请求出2011^n的后四位。
输入
第一行为一个正整数k,代表有k组数据,k<=200接下来的k行,
每行都有一个正整数n,n的位数<=200
输出
每一个n的结果为一个整数占一行,若不足4位,去除高位多余的0
样例输入
3
5
28
792
样例输出
1051
81
5521
********************************************************************************* */
/* *********************************************************************************
解题思路:
abcd
abcd
.......
abcd
abcd
abcd
*abcd
-----------
....ABCD
假设一个数(abcd)^n的结果的后四位是:ABCD,那么可以得到:
D = ( d^n )%10 进位t1 = (d^n) / 10
C = ( n*c*(d^(n-1)) + t1 ) % 10 进位t2 = ( n*c*d^(n-1) + t1 ) / 10
B = ( n*b*(d^(n-1)) + (n*(n-1)/2)*(c^2)*(d^(n-1)) + t2 ) % 10 进位t3
A = ( n*a*(d^(n-1)) + (n*(n-1)/2)*b*c*(d^(n-2)) + (n*(n-1)*(n-2)/6)*(c^3)*(d^(n-3)) + t3 )%10
其中:(n*(n-1)/2)表示组合数Cn2, (n*(n-1)*(n-2)/6)表示组合数Cn3。
由于a = 2, b = 0, c = 1, d = 1已知,那么带入可得:
D = 1, t1 = 0
C = n%10, t2= n / 10
B = ( n*(n-1)/2 + t2 ) % 10, t3 = ( n*(n-1)/2 + t2 ) / 10
A = ( 2*n + n*(n-1)*(n-2)/6 + t3) % 10
带入样例输入可知正确性。
最后的难度在于n太大了,有200位,我们可以考虑是不是存在一个数t,使得:
(2011)^t 的末四位仍然是2011??
那么就是解方程令D = 1, C = 1, B = 0, A = 2求出t>1的最小正整数,我们尝试t = 1001,满足要求。
再尝试t = 101不满足。再尝试501满足。所以就可以对所有的n,我们取末三位再模除500。
注意,t = 500时候,(2011)^t的末四位就是0001。所以(2011)^(t+1)的末四位就是2011.
********************************************************************************* */
#include < iostream >
#include < cmath >
#include < cctype >
#include < string >
#include < map >
#include < set >
#include < vector >
#include < algorithm >
#include < list >
// #include <stdlib.h>
// #include <iomanip>
using namespace std;
int main()
{
int k, n, len, ans;
int a[ 4 ], t2, t3;
string str;
cin >> k;
for ( int i = 0 ; i < k; i ++ )
{
cin >> str;
len = str.length();
n = 0 ;
for ( int j = len - 1 , t = 1 ; j >= 0 && j >= len - 3 ; j -- )
{
n += (str[j] - ' 0 ' ) * t;
t *= 10 ;
}
n %= 500 ;
a[ 0 ] = 1 ;
a[ 1 ] = n % 10 ;
t2 = n / 10 ;
a[ 2 ] = n * (n - 1 ) / 2 + t2;
t3 = a[ 2 ] / 10 ;
a[ 2 ] %= 10 ;
a[ 3 ] = ( 2 * n + n * (n - 1 ) * (n - 2 ) / 6 + t3) % 10 ;
ans = a[ 0 ] + a[ 1 ] * 10 + a[ 2 ] * 100 + a[ 3 ] * 1000 ;
cout << ans << endl;
}
return 0 ;
}