题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1104

在做这道题目一定要对同余定理有足够的了解,所以对这道题目对同余定理进行总结

首先要明白计算机里的取余计算和数学里的不一样的,计算机里的负数取余可以是负数的。例如-1%11=-1 而数学里的取余是-1%11=10

同余定理:

若a对d取余,和b对d取余的结果是相等的,那么称a,b对d是同余的。记作a≡b(mod d);这是数学里的定义。

下面看同余定理的几个性质:

1,a≡a(mod d) 数字和它本身是同余的

2,如果a≡b(mod d),b≡c(mod d);那么a≡c(mod d); 同余具有传递性、

3,如果a≡b(mod d),c≡e(mod d);那么a+c≡b+e(mod d);

4,如果a≡b(mod d),c≡e(mod d);那么a-c≡b-e(mod d);

5,如果a≡b(mod d),c≡e(mod d);那么a*c≡b*e(mod d);

6,如果ac≡bc(mod m) c!=0;那么 a≡b(mod m/gcd(c,m)) ;gcd(c,m)表示c,m的最大公约数。

7,如果a≡b(mod mi)(i=1,2,…..n) 则a≡b(mod [m1,m2…..mn]);[m1,m2…..mn]表示m1,m2….mn的最小公倍数

8,如果a≡b(mod m);那么a^n≡b^n(mod m);

以上的性质感觉做题目都没怎么用到,下面的倒是要经常用到

9,(a+b)≡((a%d)+(b%d))(mod d);

10,(a-b)≡((a%d)-(b%d))(mod d);

11,(a*b)≡((a%d)*(b%d))(mod d);

12,请特别注意%运算符不一定满足上面的性质

根据同余定理的性质给一道例题吧。

例题:求解2001 的2003 次方对13的取余数。

首先你可以算一下2001 对13取余的余数,发现是12 。那么根据性质8

2001^2003≡12^2003(mod 13).但是12^2003还是很大。一般可以是找12的几次方和1是对13同余的。可以找到12^2≡1(mod 13).

所以:(12^2)^1001≡1^1001(mod 13);

所以:(12^2)^1001*12≡1^1001*12(mod 13);

所以 12^2003≡12(mod 13).

接下来就是关于这道题目的,9,10,11,12 这四个性质。%不满足是因为%运算不像+,-,* 。例如a*b和b*a 的值是不变的,而a%b和b%a是改变的.我也说不出个所以然来,反正就是%运算会改变原本的状态。

解决办法就是倍增一下,把d变成d*b 那么(a%b)≡(((a%(b*d))%(b%(b*d)))(mod b*d).

#include <iostream>
#include <math.h>
#include <string.h>
#include <string>
#include <queue> using namespace std; int vis[1000010]; int n,k,m;
typedef struct Node
{
int num;
int step;
string way;
}Node;
int mod(int a,int b)
{
return (a%b+b)%b;
} void BFS()
{ Node * term=new Node;
Node *n1=new Node;
n1->num=n;
n1->step=0;
n1->way="";
memset(vis,0,sizeof(vis));
queue<Node*> Queue; Queue.push(n1);
while(!Queue.empty ())
{ term=Queue.front();
Queue.pop(); if(mod(term->num,k)==mod(n+1,k))
{
printf("%d\n",term->step);
cout<<term->way<<endl;
return;
}
if(vis[mod(term->num+m,k*m)]==0)
{
Node *p=new Node;
p->num=mod(term->num+m,k*m);
p->step=term->step+1;
p->way=term->way+"+";
Queue.push(p);
vis[mod(term->num+m,k*m)]=1;
}
if(vis[mod(term->num-m,k*m)]==0)
{
Node *p=new Node;
p->num=mod(term->num-m,k*m);
p->step=term->step+1;
p->way=term->way+"-";
Queue.push(p);
vis[mod(term->num-m,k*m)]=1;
}
if(vis[mod(term->num*m,k*m)]==0)
{
Node *p=new Node;
p->num=mod(term->num*m,k*m);
p->step=term->step+1;
p->way=term->way+"*";
Queue.push(p);
vis[mod(term->num*m,k*m)]=1;
}
if(vis[mod(mod(term->num,m),k*m)]==0)
{
Node *p=new Node;
p->num=mod(mod(term->num,m),k*m);
p->step=term->step+1;
p->way=term->way+"%";
Queue.push(p); vis[mod(mod(term->num,m),k*m)]=1;
}
}
puts("0");
return ; }
int main()
{
while(scanf("%d%d%d",&n,&k,&m)!=EOF)
{
if(n==0&&k==0&&m==0)
break;
BFS();
}
return 0;
}

HDU 1104 Remainder(BFS 同余定理)的更多相关文章

  1. hdu - 1104 Remainder (bfs + 数论)

    http://acm.hdu.edu.cn/showproblem.php?pid=1104 注意这里定义的取模运算和计算机的%是不一样的,这里的取模只会得到非负数. 而%可以得到正数和负数. 所以需 ...

  2. HDU 1104 Remainder (BFS(广度优先搜索))

    Remainder Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  3. HDU 1104 Remainder (BFS)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1104 题意:给你一个n.m.k,有四种操作n+m,n-m,n*m,n%m,问你最少经过多少步,使得最后 ...

  4. HDU 1104 Remainder( BFS(广度优先搜索))

    Remainder Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  5. HDU 1104 Remainder (BFS求最小步数 打印路径)

    题目链接 题意 : 给你N,K,M,N可以+,- ,*,% M,然后变为新的N,问你最少几次操作能使(原来的N+1)%K与(新的N)%k相等.并输出相应的操作. 思路 : 首先要注意题中给的%,是要将 ...

  6. hdu.1104.Remainder(mod && ‘%’ 的区别 && 数论(k*m))

    Remainder Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  7. hdu 1104 数论+bfs

    Remainder Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  8. HDU 1104 Remainder

    与前一题类似,也是BFS+记录路径, 但是有很多BUG点, 第一MOD操作与%不同i,其实我做的时候注意到了我们可以这样做(N%K+K)%K就可以化为正数,但是有一点要注意 N%K%M!=N%M%K; ...

  9. POJ 1465 Multiple (BFS,同余定理)

    id=1465">http://poj.org/problem?id=1465 Multiple Time Limit: 1000MS   Memory Limit: 32768K T ...

随机推荐

  1. C++中函数的返回值

    原文 [ 函数的返回值用于初始化在调用函数处创建的临时对象.在求解表达式时,如果需要一个地方储存其运算结果,编译器会创建一个没有命名的对象,这就是 临时对象.temporary object ] -- ...

  2. dm8127前段采集和抓拍

         高清监控(944275216) 2014-1-17 9:36:24自主研发高清网络摄像机,720P.960P.1080P系列产品,经济型.低照型.宽动态型等各种机型可选,支持onvif.P2 ...

  3. 基于swoole扩展实现真正的PHP数据库连接池

    转自:  http://rango.swoole.com/archives/265 PHP的数据库连接池一直以来都是一个难题,很多从PHP语言转向Java的项目,大多数原因都是因为Java有更好的连接 ...

  4. 【转】如何读懂Oracle文档中的语法图

    转自:http://blog.itpub.net/22990797/viewspace-750157/ Oracle文档中用到了两种表达语法的方法,语法图和BNF. BNF, Backus-Naur ...

  5. linux vi编辑器中,如何通过快捷键上下翻页?

    需求说明: 之前在vi的时候,如果想看下一页,就直接按住 ↓ 这个箭头一直翻,现在觉得有些麻烦, 就找了下上,下翻页的快捷方式.在此记录下. 记录: 1.向下翻页快捷键(下一页):Ctrl + f 2 ...

  6. NHibernate初学五之关联一对多关系

    1:创建两张表T_Country.T_Person:其中T_Person表中有一个CountryID对应T_Country的ID,一个Country可以对应多个Person CREATE TABLE ...

  7. Mongodb 与sql 语句对照

    此处用mysql中的sql语句做例子,C# 驱动用的是samus,也就是上文中介绍的第一种. 引入项目MongoDB.dll //创建Mongo连接 var mongo = new Mongo(&qu ...

  8. swift开发之--报错:Class "***ViewController" has no initializers

    因为Swift中要求变量或常量在声明时就要初始化其值,所以我们在实际开发中,声明变量或常量时使用可选类型. ?!1234 var stitle : UILabel?var webview : UIWe ...

  9. SegmentedControl的使用

    原文 http://blog.csdn.net/hmt20130412/article/details/38390493 @UISegmentedControl类似于UIButton,它可以提供多个选 ...

  10. [笔试题]黑板上写下50个数字,选两个黑板上数字a和b,在黑板写|b-a|,剩下的数字?

    在黑板上写下50个数字:1至50.在接下来的49轮操作中,每次做如下操作:选取两个黑板上的数字a和b,擦去,在黑板上写|b-a|.请问最后一次动作之后剩下的数字可能是什么?为什么?(不用写代码,不写原 ...