107. 987654321 问题 每个测试点时间限制: 0.75 sec. 给定一个正书N,你必须得到这样的数的数目,它们的平方最后几位要等于 987654321。
输入: 包含一个整数N (1<=N<=106)
输出: 打印出题目的结果
样例输入 8 样例输出 0 |
================================华丽的分割线 ================================
开始连翻译都不知道怎么翻译,感觉英文版的题目没看懂,后来到网上搜了些题解看才看题目。
算是数学的定理之类的把,一个数的平方的最后N位数只取决于那个数的最后N位数。
不信?做个实验看看吧:
for (i = 1000000000 ; i <= 9999999999 ; i ++ ){
if ((i * i) % 1000000000 == 987654321 ){
printf( " %lld\n " , i);
}
}
运行速度有一点慢,这个实验同时也证明了爆搜也不是万能的,但是咯,没有它也万万不能,……不知道说什么了,这程序运行时间太久了,,饿,也许,或许,大概,说不定,也有可能,只怕是快运行玩乐吧。。。…………额,怎么还不完…………好吧,爆了,超过long long的范围了,它同时也证明了,在这一题里不存在爆搜这一种算法,但是根据已经输出得部分:
1111111111
1119357639
1380642361
1388888889
1611111111
1619357639
1880642361
1888888889
2111111111
2119357639
2380642361
2388888889
2611111111
2619357639
2880642361
2888888889
看到了吧,很明显最后九位是相同的,所以需要手工算出9位所有的可能性,然后再根据这个规律来计算就可以了! 同样,你们可以自己写代码验证1~8位都没有这样的数。
十位数第一位必须不等于0,不然就是九位数了,也就是第一位有9种可能,后面九位有8种可能是题目要求的数,10位总共就有72位了。11位数字第一位必须不为0,第二位可以为0,就有90种可能,乘以后九位的8种……还有要注意的就是千万别妄想把个数保存起来,看看数据范围就知道,果断直接输出!
#include < stdlib.h >
int main( int argc, char ** argv)
{
int n, i;
scanf( " %d " , & n);
if (n < 9 ){
printf( " 0\n " );
} else if (n == 9 ){
printf( " 8\n " );
} else {
printf( " 72 " );
for (i = 11 ; i <= n; i ++ ){
printf( " 0 " );
}
printf( " \n " );
}
return 0 ;
}