余数

蓝桥杯入门训练

点点圈 提交于 2020-01-06 03:08:27
一、 Fibonacci数列 【 注意:此题的做法就是禁止直接算出和再进行取余,这样会造成运行超时 】 问题描述   Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。   当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。 输入格式   输入包含一个整数n。 输出格式   输出一行,包含一个整数,表示Fn除以10007的余数。   说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单。 样例输入   10 样例输出   55 样例输入   22 样例输出   7704 数据规模与约定   1 <= n <= 1,000,000。 1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 // TODO Auto-generated method stub 6 Scanner mm = new Scanner(System.in); 7 int n = mm.nextInt(); 8 int[] aa = new int[1000000]; 9 aa[1]

加密和解密

*爱你&永不变心* 提交于 2019-12-24 11:55:05
1、MD5加密解密 MD5 加密是输入任意长度的信息,经过处理,输出128位的信息,不同的输入得到的不同的结果,但是相同的输入一定得到相同的结果。并且根据这 128 位的信息无法推出明文信息,所以 MD5 加密是不可逆的,MD5算法无法破解。 MD5 是单向散列函数,散列算法也称哈希算法,哈希算法不可逆。比如10除以3余数为一,4除以3余数也为一,但余数为一的就不知道这个数是哪个了,就算是设计这个加密算法的人都不知道。 MD5 可以用来加密用户密码,密码验证的原理是同一密码加密后的生成的 128 位信息一定相同,你输入密码加密后才能知道你的密码是否正确。这也是为什么扣扣密码只能重置,不能找回的原因。 可参考: https://blog.csdn.net/dawn_after_dark/article/details/54429766 来源: https://www.cnblogs.com/wenxuehai/p/11981523.html

POJ1006: 中国剩余定理的完美演绎

岁酱吖の 提交于 2019-12-23 22:09:54
问题描述 人自出生起就有体力,情感和智力三个生理周期,分别为23,28和33天。一个周期内有一天为峰值,在这一天,人在对应的方面(体力,情感或智力)表现最好。通常这三个周期的峰值不会是同一天。现在给出三个日期,分别对应于体力,情感,智力出现峰值的日期。然后再给出一个起始日期,要求从这一天开始,算出最少再过多少天后三个峰值同时出现。 问题分析 首先我们要知道,任意两个峰值之间一定相距整数倍的周期。假设一年的第N天达到峰值,则下次达到峰值的时间为N+Tk(T是周期,k是任意正整数)。所以,三个峰值同时出现的那一天(S)应满足 S = N1 + T1*k1 = N2 + T2*k2 = N3 + T3*k3 N1,N2,N3分别为为体力,情感,智力出现峰值的日期, T1,T2,T3分别为体力,情感,智力周期。 我们需要求出k1,k2,k3三个非负整数使上面的等式成立。 想直接求出k1,k2,k3貌似很难,但是我们的目的是求出S, 可以考虑从结果逆推。根据上面的等式,S满足三个要求:除以T1余数为N1,除以T2余数为N2,除以T3余数为N3。这样我们就把问题转化为求一个最小数,该数除以T1余N1,除以T2余N2,除以T3余N3。这就是著名的中国剩余定理,我们的老祖宗在几千年前已经对这个问题想出了一个精妙的解法。依据此解法的算法,时间复杂度可达到O(1)。下面就介绍一下中国剩余定理。

NOIP2000TG T1 进制转换

Deadly 提交于 2019-12-23 05:51:31
题目链接 题意: 求$n$的$r$进制表示法$(r<0)$。 程序1(60pt): 若$r>0$,每次用$r$除$n$,记录余数,用商替换$n$,最后倒序输出余数。 然而这里$r<0$,直接整除可能会出现负的余数,然而没有负的数码,所以我们有 $n=\lfloor\frac{n}{d}\rfloor*d+r=(\lfloor\frac{n}{d}\rfloor+1)*d+(r-d)$ 于是出现负余数时候,除数$++$,余数减除数就可以了。 然而$r<-10$时,十个基础数码不够用了,于是$60pt$。 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=16; int n,r,s[N+3]; int main(){ scanf("%d%d",&n,&r); int nn=n; int p=0,a,b; while(n!=0){ p++; a=n/r; b=n%r; if(b<0){ a++; b=n-a*r; } n=a; s[p]=b; } printf("%d=",nn); for(int i=p;i>=1;i--) printf("%d",s[i]); printf("(base%d)

加减交替法(不恢复余数法)

…衆ロ難τιáo~ 提交于 2019-12-23 00:40:38
前言 加减交替法处理思想是先减后判,如果减余数后发现不够减,则下一步中改为加除数操作。 运算一步加减完成时,遵循的规则 当余数为正时,表示够减,即商上1,在进行下一次商时,将余数(此时为正)左移一位,减去除数。 当余数为负时,表示不够减,即商上0,在进行下一次商时,将余数(此时为正)左移一位,加上除数。 运算时需要双符号补码,所以应先把给定的定点数转换为补码形式,需要注意的是,除数的负数也要转换为双符号补码,方便后面作减法。因为在计算机中减一个数等于加这个数的负数。而补码正是用来做加减法的。 操作的步数n 是由要求的n位商决定的,如果第n步 余数为负,则需增加一步恢复余数,即 +Y ,增加的这一步不移位。 实例练习 题目: X=0.1011 Y=0.1101 用加减交替法求X/Y 解: [X]补 =0.1011 对应的双符号位补码为 00 1011 [Y]补 =0.1101 对应的双符号位补码为 00 1101 [-Y]补 =1.0011 对应的双符号位补码为 11 0011 开始计算,X先减一下Y,即X+[-Y] 我们用双符号补码来做 根据规则,结果若是负数,代表不够减,下一步应该+Y,则 商上0 ,并且在进行下一步之前让余数左移一位。即余数11 1110变为 11 1100 开始下一步 根据规则,结果若是正数,代表够减,下一步应该-Y,(-Y 就是加上-Y) 则 商上1

最大的余数题解

老子叫甜甜 提交于 2019-12-17 17:42:02
其实本题的难度真心不高,但是可以完整说明数据分析、标程、随机数生成、对拍等部分。 题目链接 原题来自计蒜客的某次比赛。计蒜客对应的链接为 https://nanti.jisuanke.com/t/42227 。 或者我自己OJ的链接为 http://47.110.135.197/problem.php?id=5150 。 题面 给定一个正整数 n,请找出一个不大于 n 的正整数 p,使得 n 除以 p 的余数最大,并求出这个最大的余数。 输入 只有一行,包含一个正整数 n。 输出 只有一行,包含你的答案。 样例输入 5 样例输出 2 数据范围 一共 20 个测试数据 对于前 30% 的数据,1 ≤ n ≤10。 对于前 60% 的数据,1 ≤ n ≤10^6。 对于前 90% 的数据,1 ≤ n ≤ 10^18。 对于前 100% 的数据,1 ≤ n ≤ 10^1000。 题目分析 解题思路 求余数,而且要求余数最大。哪么必然意味着除数要最小,哪么除数必然为 1。也就是说,这题就是一个 2 的余数问题。进一步分析,我们可以知道如果被除数为奇数,哪么这个最大的余数为 n/2;如果被除数为偶数,哪么这个最大的余数为 n/2 - 1。等效于(n-1)/2。 数据范围分析 30%的数据,1 ≤ n ≤10。可以用int可以表示 n。 60% 的数据,1 ≤ n ≤10^6

redis缓存策略

烈酒焚心 提交于 2019-12-16 14:44:56
常用策略有“求留余数法”和“一致性HASH算法” redis存储的是key,value键值对 一、求留余数法 使用HASH表数据长度对HASHCODE求余数,余数作为索引,使用该余数,直接设置或访问缓存。 计算key的HashCode 缺点:增加服务器,由于除数不一样了,之前缓存的数据都没办法访问了,即不支持热部署【扩展】 二、一致性HASH算法 一致性HASH算法通过一个叫做一致性HASH环的数据结构,实现KEY到缓存服务器的HASH映射。 算法过程如下: 先构造一个0到 2 32 的整数环,然后将服务器节点的Hash值,放在该环上(可以理解为将你的ip做hash,将ip的HashCode放在环上)。然后根据需要缓存的数据的Key,计算Key的HashCode,然后在环上,顺时针查找距离这个Key的Hash值最近的缓存服务器的节点,然后将Value,存储到该服务器节点上。 这是当缓存服务器集群需要扩容的时候,只需要将新加入的节点的HashCode,放入一致性Hash环中,由于Key是顺时针查找距离最近的节点,因此,新加入的节点只影响整个环中的一小段。 请参见上图,如果我们新加入的服务器节点Node3,在Node1和Node2之间,如下图: 那么受影响的区域,只是Node2到Node3之间(顺时针)的缓存,此区间的缓存数据,加入节点之前是缓存在Node1上的

【剑指offer】二进制中1的个数

淺唱寂寞╮ 提交于 2019-12-14 22:09:12
这个题的思路是比较简单的 大家先想一下,一个十进制整数是如何转化为二进制数的??? 我们采用的是“除2取余,逆序排列"法。具体做法是:用2整除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。 所以这个思路就是:和2%,看是否为1,为1,结果加1,否则继续 但是我们需要思考一下代码如何优化的问题? 如二进制是100000000000000000000,那我们需要的循环次数是多少,这个时间复杂太高,我们需要优化 所以一下均为优化过的方法 Java 1、 public class Solution { public int NumberOf1 ( int n ) { int res = 0 ; while ( n != 0 ) { n &= ( n - 1 ) ; //我将这个方法称为抹0法,将最右边的1抹掉, res ++ ; } return res ; } } 2、 public class Solution { public int NumberOf1 ( int n ) { int res = 0 ; while ( n != 0 ) { n -= n & ( ~ n + 1 ) ; //这对与方法1相似,都是将最右侧的1抹掉

CRC检验码计算——C语言(CRC8/16/32)

自闭症网瘾萝莉.ら 提交于 2019-12-12 13:52:47
1、基本概念 1.1、循环冗余检测(Cyclic Redundancy Check,CRC) CRC编码也被称为多项式编码(polynomial code),因为该编码能够将要发送的比特串看作是系数为 0 和 1 的一个多项式。对比特串操作被解释为多项式算术。 1.2、CRC参数 D:D数据拥有 d 比特 G:发送方和接收方需要协商一个 r+1 比特模式,称为生成多项式(G), G 的最高有效位比特(最高位)和 最低有效位比特(最低位)必须为 1 R:发送方选择 r 个附加比特,称为 R(CRC校验码) (1) 计算 :R 是数据 D 通过 模 2 除法 除 G 运算得到的(姑且这么说)余数, 这个 R 就是 FCS(检测帧序列) ,发送时把 R 附加到数据 D 后面。 (2) 检验 :一共接收有 d+r 个比特,用模 2 算术恰好能够被 G 整除(没有余数),即 (D+R)/ G,如果余数为 0,接收方认为数据正确而被接收,否则接收方知道出现了差错。 1.3、CRC原理解释 所有 CRC 计算采用模 2 算术,即在加法中不进位,在减法中不借位,意味加法和减法是相同的, 等价于操作数的按位异或(XOR)运算 ,而不是需要借位运算。 例如: D = 10110011,d = 8 G = 11001,r = 4 通过计算得到 R = 0100 在这种情况下传输 12 个比特是

C语言程序设计100例之(24):数制转换

◇◆丶佛笑我妖孽 提交于 2019-12-12 12:42:45
例24 数制转换 题目描述 请你编一程序实现两种不同进制之间的数据转换。 输入格式 共三行,第一行是一个正整数,表示需要转换的数的进制n(2≤n≤16),第二行是一个n进制数,若n>10则用大写字母A-F表示数码10-15,并且该n进制数对应的十进制的值不超过1000000000,第三行也是一个正整数,表示转换之后的数的进制m(2≤m≤16)。 输出格式 一个正整数,表示转换之后的m进制数。 输入样例 16 FF 2 输出样例 11111111 (1)编程思路。 十进制整数转换为R进制整数的基本方法是:“除R取余”。具体做法为:对于十进制数整数,用R连续除要转换的十进制整数及各次所得之商,直除到商等于0时为止,则各次所得之余数即为所求R进制整数由低位到高位的值。这个过程可以写成一个简单的循环。 一般而言,对于任意的R进制数 A n-1 A n-2 …A 1 A 0 可以表示为以下和式: A n-1 ×R n-1 +…+A 1 ×R 1 +A 0 ×R 0 (其中R为基数) 这个和式也称为“按权展开式”。 R进制数转换为十进制数的基本方法是将R进制数的各位按权展开相加即可。 本例的思路是:将输入的n进制整数按权值展开后转换为十进制整数,再将所得的十进制整数采用“除m取余”转换为m进制整数即可。 (2)源程序。 #include <stdio.h> int main() { char