韩信点兵 中国剩余定理
1077 韩信点兵
时间限制:500MS 内存限制:65536K
提交次数:1103 通过次数:99
题型: 编程题 语言: G++;GCC
Description
相传汉高祖刘邦问大将军韩信统御兵士多少,韩信答说,每3人一列余1人、5人一列余2人、7人一列余4人、13人一列余6人、 17人一列余2人、19人一列余10人、23人一列余1人、29人一列余11人。
刘邦茫然而不知其数。你呢? 你是一位优秀的程序员,请你帮刘邦解决这一问题。
输入格式
要求由键盘输入A,B,C,D,E,F,G,H,a,b,c,d,e,f,g,h十六个数,分别代表每A人一列余a、每B人一列余b、每C人一列余c、每D人一列余D、每E人一列余e、每F人一列余f、每G人一列余g、每H人一列余h,其中A,B,C,D,E,F,G,H为互不相等的质数
输出格式
输出总兵士数,要求输出满足条件的最小的一个,但要满足8种排法的每一种排法至少可排一列。(保证给的数据,有结果且计算的结果不会超过2的63次方)
输入样例
2 3 5 7 11 13 17 19
1 1 1 1 1 1 1 1
输出样例
9699691
中国剩余定理(CRT)的表述如下
设正整数两两互素,则同余方程组
有整数解。并且在模下的解是唯一的,解为
其中,而为模的逆元。
中国剩余定理:
先考虑这样一个问题:
X % 3 = 2
X % 5 = 3
X % 7 = 2
minans = 23
怎么做呢?可以先把除以3余数是2的数字先写出来:2 5 8 ....
再把除以5余数是3的写出来 3、8、....
那么共同的数字是8,所以8就是除以3余2且除以5余3的最小数字。。
中国剩余定理也是类似的思想
对于每条等式,都找出一个val,使得val % mod[i] = r[i]且 val % 其他数字是等于0的
第一条式子,这个val = 140
关于怎么找每条式子的val,可以想到用逆元,先解出t % mod[i] = 1,再把r[i] * t即是val。因为这个时候余数就是r[i]了,
r[i] * t % mod[i] = ((r[i] % mod[i]) * (t % mod[i])) % mod[i] = r[i]
下面来讨论下为什么要val % 其他数字是等于0的。
这里是根据余数的性质,
上面的式子,val分别是140、63、30
把他们加起来 % (mod[1] * mod[2] * ..... *mod[n])是答案。
先求解前两个的答案,就是先满足除以3余2,除以5余3的数。
ans = (140 + 63) % 15
这里的140满足%3 = 2而且%其他数字 = 0
这样的好处是不会相互影响。
满足一个等式,而不会影响另一个等式
注意这里要满足必须排至少一列,暴力特判就好了
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL;#include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> LL exgcd (LL a,LL mod,LL &x,LL &y) {//求解a关于mod的逆元 ★:当且仅当a和mod互质才有用if (mod==0) {x=1;y=0;return a;//保留基本功能,返回最大公约数 }LL g=exgcd(mod,a%mod,x,y);LL t=x; //这里根据mod==0 return回来后,x=y; //x,y是最新的值x2,y2,改变一下,这样赋值就是为了x1=y2y=t-(a/mod)*y; // y1=x2(变成了t)-[a/mod]y2;return g; //保留基本功能,返回最大公约数 } LL get_inv(LL a,LL MOD) //求逆元。记得要a和MOD互质才有逆元的 {LL x,y; //求a关于MOD的逆元,就是得到的k值是a*k%MOD==1LL GCD=exgcd(a,MOD,x,y);if (GCD==1)//互质才有逆元可说return (x%MOD+MOD)%MOD;//防止是负数else return -1;//不存在 } const int maxn = 100; LL r[maxn], mod[maxn]; LL CRT(LL r[], LL mod[], int n) { // X % mod[i] = r[i]LL M = 1;LL ans = 0;for (int i = 1; i <= n; ++i) M *= mod[i]; // cout << M << endl;for (int i = 1; i <= n; ++i) {LL MI = M / mod[i]; //排除这个数ans += r[i] * (MI * get_inv(MI, mod[i])); //使得MI % mod[i] = 1 // cout << get_inv(MI, mod[i]) << endl;ans %= M;} // if (ans < 0) ans += M;while (true) {int i;for (i = 1; i <= n; ++i) {if (ans < mod[i]) {ans += M;break;}}if (i == n + 1) return ans;}return ans; } void work() {int n = 8;for (int i = 1; i <= n; ++i) cin >> mod[i];for (int i = 1; i <= n; ++i) cin >> r[i];cout << CRT(r, mod, n) << endl; } int main() { #ifdef localfreopen("data.txt","r",stdin); #endifwork();return 0; }
View Code
转载于:https://www.cnblogs.com/liuweimingcprogram/p/5918667.html
韩信点兵 中国剩余定理相关推荐
- 韩信点兵-中国剩余定理(练习)
http://acm.nyist.net/JudgeOnline/problem.php?pid=34提交地址 韩信点兵-中国剩余定理. 题目能够用枚举非常easy的做出来,在这里写是为了运用一下刚刚 ...
- 中国剩余定理(Chinese Remainder Theorem)
中国剩余定理 民间传说着一则故事--"韩信点兵". 秦朝末年,楚汉相争.一次,韩信将1500名将士与楚王大将李锋交战.苦战一场,楚军不敌,败退回营,汉军也死伤四五百人,于是韩信整顿 ...
- 为什么计算机的编码那么多,为什么中国剩余定理可用于计算机编码?
我们已经知道了"中国剩余定理",即"韩信点兵"问题,它是中国古代数学中的一项重大成就,其内容属于数论中的一次同余数组的解法.而这一古老的知识,现在在计算机编码方 ...
- 【一级讲解】韩信点兵——中国剩余定理
韩信点兵 相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排.五人一排.七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了.输入3个非负整数a,b,c ,表示每种队形排尾 ...
- 三人同行七十稀 - 中国剩余定理浅析
我国明朝有位大数学家叫程大位,他在解答"物不知其数"问题(即:今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩2,问物几何?)用四句诗概括这类问题的解决: "三人同 ...
- 数论 · 中国剩余定理(CRT)
UPDATE 2021 - 12 - 10:补充扩展中国剩余定理 EXCRT,额外开了一篇博客写. 2021 - 12 - 21:修改了一两句话,更严谨一些. 问题概述 小奥里的韩信点兵问题: { x ...
- 数论-中国剩余定理(crt) 与拓展中国剩余定理(excrt)
中国剩余定理(crt) [用途] 求方程组中最小的非负整数解X X ≡ { a 1 ( m o d m 1 ) a 2 ( m o d m 2 ) . . . a n ( m o d m n ) X\ ...
- 小议中国剩余定理兼怀金庸
本是几个月前整理完备hash构造时打算写的,不意拖到了金庸先生去世.<射雕英雄传>中那一次精彩绝伦的数学启蒙,不亚于光明顶上张无忌出尽风头的擂台秀.瑛姑与黄蓉的几轮口头交锋,涵盖了n阶幻方 ...
- 从韩信点兵和勾股弦说起—— 漫谈基础数学的古今中外
从韩信点兵和勾股弦说起-- 漫谈基础数学的古今中外 前言 基础数学的范畴,大体上也就是现代中学和大一数学课程中所要学的代数.几何与分析的基础知识:它不但是数学的根本,也是整个科技发展的基础,可以说是人 ...
最新文章
- matlab mnl,LaTex中插入VISO 和 MATLAB 经验总结
- python详细基础教程-Python基础教程,Python入门教程(非常详细)
- 在kindle fire 上安装CM10 Jelly Bean ROM
- log4net在winform中release后不工作的原因
- Jdk1.8新特性(三)——方法引用::
- java虚拟机规范 51cto_java虚拟机
- Java ObjectOutputStream reset()方法与示例
- java康纳塔评测_JAVA性能、扩展对比
- 6. PHP 正则表达式
- 用Theano学习Deep Learning(三):卷积神经网络
- win10解压安装mysql缺少MSVCR120.dll文件的问题
- IDEA插件系列(67):ReadHub插件——新闻阅读器
- python基础-包文件批量导入导出
- 大数据技术之Spark Streaming概述
- LLaMA模型文件 (搬运工)
- WPF---RenderTransform图形旋转,缩放
- 电脑硬件:蓝屏的常见解决方案
- 报错 java: 程序包javax.servlet.http不存在
- 【前端第四课】CSS值和单位;CSS文字排版;CSS变换,过渡,动画;CSS定位
- IT人职业规划(绝对给力)
热门文章
- Kafka rebalance触发条件
- 【C基础练习题】第一章:输入和输出 | 基础练习题 | 提供题解
- 医学图像——医学坐标体系
- html meat 标签 菜鸟,seo技术之META标签
- 水下机器人项目!大创!包含solidworks模型,程序,PCB,上位机,实物视频演示,项目报告。
- 《先进PID控制 MATLAB仿真 第2版 刘金琨等编》【shallow】
- 【ZOJ 4062】Plants vs. Zombies
- openPTrack v2 安装 | 3、OpenPTrack v2 模块编译
- 微信小程序支付组件开发实战
- 设备Kingston DataTraveler 3.0无法连接到理想的主机控制器。将尝试将该设备连接到可用的最佳主机控制器......