常见形式:
1.给定某个数学规律,要求用输入数据模拟从而验证这个规律,并输出结果。but 测试数据范围很大,真的用模拟可能会超时。
2.给定某种对数的繁琐操作,要求输出对输入数据进行该种操作得出的结果,but 对于数据范围,模拟可能会超时||操作过程中,产生的数据非常大,使得模拟不现实。
输出一个数
Description
给你一个非负整数X,现将X!(X的阶乘)各位数相加,得到一个新的X,再将X的各位数相加...
直到X变成个位数为止。问最后X是多少
Input
第一行输入一个整数n(n<=1000),表示有n个样例
接下来n行每行输入一个x(x<=1000)
Output
输出n行 每行输出一个数
Sample Input 1
3 2 3 2018
Sample Output 1
2 6 9
分析:
测试数据最大为1000,对每个x首先递归求阶乘,1000的阶乘非常大,甚至超过了long long的范围,直接模拟不现实。
此时考虑打表找规律。
通过打表可以发现,当x>=6时,结果都是9(如果不放心,可以输出更多的数)。这就是这道题的规律,还是比较容易找到的。
打表代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
LL jc(LL x)//求阶乘
{
if(x==1) return 1;//结束
return x*jc(x-1);
}
LL seek(LL x)//求各位数的和
{
LL ans=0;
while(x)
{
ans+=x%10;
x/=10;
}
return ans;
}
void print(LL x)
{
do{
x=seek(x);
}while(x/10!=0);
printf("%ld\n",x);
return ;
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int x;
scanf("%d",&x);
LL sum=jc(x);//求阶乘
print(sum);
}
return 0;
}
结论代码:
#include<iostream>
#include<cstdio>
using namespace std;
int ans[6]={0,1,2,6,6,3};
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int x;
scanf("%d",&x) ;
if(x<=5) printf("%d\n",ans[x]);
else printf("%d\n",9);
}
return 0;
}
Fibonacci 数列与⻩⾦分割

分析:可见这道题数据范围非常大,用模拟会超时。这时我们考虑打表找规律。
同样通过打表我们可以发现,当n>=20时,结果都是相同的。
#include<iostream> using namespace std; int f[100]; int main() { f[1]=1; f[2]=1; for(int i=3;i<=25;i++) { f[i]=f[i-1]+f[i-2]; } long long n; scanf("%ld",&n); if(n<=19) printf("%.8lf\n",(double)f[n]/f[n+1]); else printf("%.8lf\n",(double)f[20]/f[21]); return 0; }
结论代码: