本文主要是介绍2016-HNUST校赛-addition,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接:addition
解题思路:因为结果要对100007求余,那么最多模拟100007次定会出现循环节,找出循环节的长度,这部分是可以直接根据周期算出了的,但循环节出现的位置前面以及循环节段的最后一个数的后面都可能会有一段非循环部分(即完整循环的一部分),所以只需在对这两个地方单独处理即可,比赛的时候想找出它的公式,但在求余那部分还是失败了,求循环节这种方法是需要学会!
#include#include#include#include#define N 100007
using namespace std;
typedef long long LL;
LL vis[N+20],pos[N+20],dp[N+20];
int main()
{
LL a,n,m,i,p,t,ans,sum,r1,r2,r3,T;
while(~scanf("%lld%lld%lld",&a,&n,&m)){
memset(vis,0,sizeof(vis));
dp[0]=a%m,vis[dp[0]]=1,pos[dp[0]]=0;//初始化第一部分
for(i=1; ;i++){
dp[i]=(dp[i-1]*10 + a)%m; //模拟求值
sum=dp[i];
if(vis[sum]) { //当前值如果之前出现过,就表示开始出现循环了,就不用继续模拟下去了
p=i; //记住当前位置
T=i-pos[sum]; //记录循环节的长度,亦是周期
break;
}
vis[sum]=1; //标记当前和sum已经出现过
pos[sum]=i; //记住sum第一次出现的位置
}
r1=r2=0,r3=0; //r1代表头部那一段,r2表示中间循环的部分,r3表示尾部那一段
for(i=0;i
这篇关于2016-HNUST校赛-addition的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!