W3 school 菜鸟教程 我要自学网 信息学奥赛NOI 花哥的博客 不逼自己一把,怎知自己有多优秀——校长语录

大数据计算中取模运算一错分析

1618:越狱

时间限制: 1000 ms         内存限制: 524288 KB
提交数: 223     通过数: 91 
【题目描述】
原题来自:HNOI 2008

监狱有连续编号为 11 到 nn 的 nn 个房间,每个房间关押一个犯人。有 mm 种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。求有多少种状态可能发生越狱。

【输入】
输入两个整数 mm 和 nn。

【输出】
可能越狱的状态数,对 100003100003 取余。

【输入样例】
2 3
【输出样例】
6

1618越狱

#include<bits/stdc++.h>
using namespace std;
int p=100003;
long long qm(long long m,long long n)
{
    if(n==0)return 1;
    if(n==1)return m%p;
    long long t=qm(m,n/2);
    t=(t*t)%p;
    if(n%2)t=t*m;
    return t%p;    
}
int main()
{
    long long m,n;
    cin>>m>>n;
    m%=p;
    cout<<(qm(m,n)-m*qm(m-1,n-1))%p;
    return 0;
}

错误代码

老规矩,样例能过,提交后一对9错(答案错误)。首先排查算法逻辑错误,想了又想,把每一个环节都从数学的角度复查一遍,还是确认逻辑没问题。那就可以是取模运算了。在朋友们的帮助下,发现(qm(m,n)-m*qm(m-1,n-1))%p可能出现负数,然后取模运算也不能把它变成正数。所以最后这一算改为(qm(m,n)-m*qm(m-1,n-1)+p)%p,但还是一对9错。期间另一朋友发了一个程序,看了下逻辑上一模一样。后来详细比较和另一朋友提醒下,发现(qm(m,n)-m*qm(m-1,n-1)+p)%p中加一个p不能解决负数问题,因为前面有一个m倍,所以需要把m*qm(m-1,n-1)也取模,最后+p就可以解决负数问题了,也就是说最后一步改为(qm(m,n)-(m*qm(m-1,n-1))%p+p)%p就可以了。

 

特别明谢ybt.ssoier.cn教师群里所有朋友们,你们的帮助给了我无尽的前进的动力

 

posted @ 2019-03-06 10:04  耍人  阅读(515)  评论(0编辑  收藏  举报