规律打表,找循环节,类似2016湘潭那个2016
2991: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
思路:
2011的n次方,这个n很大,小于等于200位,一看就是字符串读入,因为只取最后四位,这时候要推测出题者用意,2011的次方后四位是否会出现一个循环节。
想起2016年湘潭赛那个2016,也是快速乘法,发现有循环节之后更加好做。
这里一样。预处理打表,注释部分,打出i的出现相同的a[i]下标,发现1 501 1001 1501。所以循环节是500.
因为只留最后4位,所以每次打表的时候取模10000,留下最后四位就好。
因为500一循环,只要最大三位数即可,没有三位的直接转换。
注意n的位数,一开始只开了25,发生玄学问题。。。。(25放全局可以过,250放局部可以过,RE)
#include <bits/stdc++.h> using namespace std; const int maxn = 10000+5; int a[maxn] = {0,2011}; void pre() { for(int i = 2; i <= 10000; i++) { a[i] = (a[i-1]*2011)%10000; } } int main() { pre(); // for(int i = 1; i <= 10000; i++) { // if(a[i]==2011) { // cout<<i<<endl; // } // } int T; scanf("%d",&T); while(T--) { char str[250]; int n = 0; scanf("%s",str); int len = strlen(str); if(len>=3) { // for(int i = len-1,j = 0; i >= len-3; i--,j++) { // cout<<(pow(10,j))<<endl; // n += (str[i]-'0')*(pow(10,j)); // } for(int i = len-3; i <= len - 1; i++) { n = n*10 + str[i]-'0'; } } else { n = atoi(str); } n %= 500; printf("%d\n",a[n]); } return 0; }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步