最右算法
① 所有进制的算法
#include <stdio.h>void a();void b();void c();void main(){ int s; do { printf("0.退出\n1.十进制~二进制\n2.十进制~八进制\n3.十进制~十六进制\n请选择:"); scanf("%d",&s); if(s==0) { break; } switch(s) { case 1: a();break; case 2: b();break; case 3: c();break; default:printf("输入有误!请输入0~4之间的数\n");break; } }while(1);}void a(){ int num,p[100],n=0,i; printf("请输入一个十进制整数:"); scanf("%d",&num); while(num!=0) { p[n]=num%2; num/=2; n++; } for(i=n-1;i>=0;i--) { printf("%d",p[i]); } printf("\n");}void b(){ int num,p[100],n=0,i; printf("请输入一个十进制整数:"); scanf("%d",&num); while(num!=0) { p[n]=num%8; num/=8; n++; } for(i=n-1;i>=0;i--) { printf("%d",p[i]); } printf("\n");}void c(){ int num,p[100],n=0,i; printf("请输入一个十进制整数:"); scanf("%d",&num); while(num!=0) { p[n]=num%16; num/=16; n++; } for(i=n-1;i>=0;i--) { if(p[i]<10) { printf("%d",p[i]); } else { switch(p[i]) { case 10: printf("A"); break; case 11: printf("B"); break; case 12: printf("C"); break; case 13: printf("D"); break; case 14: printf("E"); break; case 15: printf("F"); break; } } } printf("\n");} 答案补充 10进制数转化成R进制数就是不断地 取余、整除,最后把所有余倒序排列 比如:6转化成2进制数的步骤是,6取2的余是0,整除得3,3取2的余是1,整除得1,1取2的余是1,整除2得0,计算结束,再把所有余倒序排列,即110。
其它进制也是同样的道理,如果进制大于10,就要用ABCD来分别表示10进制中的(10、11、12、13、14),可以去查询下权的概念
② 二叉树算法—广度搜索算法使用以及变形
使用迭代来实现广度搜索
思索下面几个算法题:
102. 二叉树的层序遍历
429. N 叉树的层序遍历
107. 二叉树的层序遍历 II
101. 对称二叉树
广度搜索:即在水平维度一层层的去解析二叉树节点。即节点先进先出(队列结构)。
最简单的算法如上所示。
看到这个题,就想到了广度搜索算法。
难点: 如何将每一层的节点均存储到一个集合中?
开始想到的思路是: 每一层末尾节点后加一个标识位表示分层?但是这种思路是不太好的!
那如何实现分层存储?
思路 :首先广度搜索需要有一个大循环来遍历树,在大循环内部可不可以使用内层循环来遍历层呢? 即大循环开启的是每层的查询,小循环开启的是每层节点的查询?
难点 :如何控制内循环的循环次数?
思路 :每遍历一个节点,会将节点所以子节点存储到队列中。当遍历完一次,结束内循环时,队列里面存储的均是下一层的节点, 而队列的大小就是内循环的次数。
这个题如何使用广度搜索来实现?
说实话我是没有思路的,可能是广度遍历二叉树对我影响太深,以至于广度搜索和核心我到现在都没明白。
这个题的难点在于:如何比较最左和最右两个节点是否相等。
而本题的思想是两个节点的比较,那么在循环开始前,将root的左右节点放入到队列中,开启循环后,在队列中取出两个节点进行比较,若两个节点相等, 按照顺序,将最左和最右两个节点在次放入到队列中。
每次取出来的两个节点是有序的(最左和最右)
③ 全排列or递归 算法题,求一个最优算法
这题并不是全排列,如果全排列是O(n!*n)的复杂度,完全无法接受,正解是概率期望DP
#include<stdio.h>
doubledp[1001];
intmain()
{
dp[0]=0;//0个人当然是0
inti;
doublesum=0;//记录前面所有dp的和
for(i=1;i<=1000;i++)
{
dp[i]=sum/i+1;
sum+=dp[i];
}
while(~scanf("%d",&i))
printf("%.2lf
",dp[i]);
}
④ 我在最右纸飞机功能被禁号了能打开吗,
不可以的,要打开需要去找客服申诉解封。
目前,纸飞机有两部分:基于LBS定位的在线“配对聊天”和“附近人聊天”。在线配对聊天可以根据聊天对象选择要匹配的性别(目前只匹配性别选项);对于附近的纸飞机,用户自己抛出一个纸飞机,附近的人根据地理位置捡起扔的纸飞机,选择和自己开启聊天。
值得一提的是,纸飞机的匿名聊天5分钟“聊后即焚”,所以不必担心自己的隐私。如果聊天愉快,双方可以在最后一分钟同时点亮,这样就可以自由聊天并保存聊天记录。头像也是纸飞机自己制作的,不能自己上传头像,这样更大程度上保护了用户的隐私。
(4)最右算法扩展阅读:
对于年轻用户来说,纸飞机为他们提供了一种认识新朋友的方式(这种形式有点类似于soul)。具体规则如下:
1、通过该算法,随机配对到一个临时聊天框中,双方除性别外的所有信息都是不可见的。(头像是随机出现的卡通头像)
2、在5分钟的聊天时间内,任何一方退出聊天都将终止。聊天结束后,可以查看对方是谁,然后单击进入对方主页。
3、倒数到1分钟时,双方可以选择是否继续聊天。如果双方都确定,聊天框会保留下来,可以看到对方。否则,聊天将在时间结束时终止。
⑤ 二进制转化为十进制的算法
从最低位(最右)算起,位上的数字乘以本位的权重,权重就是2的第几位的位数减一次方。
比如第2位就是2的(2-1次)方,就是2;第8位就是2的(8-1)次方是128。把所有的值加起来。
2(1-1)代表2的0次方,就是1;其他类推
比如二进制1101,换算成十进制就是:1*2(1-1)+0*2(2-1)+1*2(3-1)+1*2(4-1)=1+0+4+8=13。
(5)最右算法扩展阅读:
1、二进制转换为八进制:
把二进制的数从右往左,三位一组,不够补0
列:111=4+2+1=7
11001拆分为 001和011,001=1,011=2+1=3。
那么11001转换为八进制就是31。
2、二进制转换为十六进制:
参照二进制转八进制,但是它是从右往左,四位一组,不够补0
列子:1101101拆分为1101、0110
分别计算两个二进制的值,1101=8+4+0+1=13,十六进制中13为D
0110=4+2=6,那么二进制1101101转换为十六进制就是6D。
参考资料:网络-数制
⑥ 二进制计算方法是什么
加法:
(1)首先是最右数码位相加。这里加数和被加数的最后一位分别为“0”和“1”,根据加法原则可以知道,相加后为“1”。
(2)再进行倒数第二位相加。这里加数和被加数的倒数第二位都为“1”,根据加法原则可以知道,相加后为“(10)2”,此时把后面的“0”留下,而把第一位的“1”向高一位进“1”。
(3)再进行倒数第三位相加。这里加数和被加数的倒数第二位都为“0”,根据加法原则可以知道,本来结果应为“0”,但倒数第二位已向这位进“1”了,相当于要加“被加数”、“加数”和“进位”这三个数的这个数码位,所以结果应为0 1=1。
(4)最后最高位相加。这里加数和被加数的最高位都为“1”,根据加法原则可以知道,相加后为“(10)2”。一位只能有一个数字,所以需要再向前进“1”,本身位留下“0”,这样该位相加后就得到“0”,而新的最高位为“1。
减法:
(1)首先最后一位向倒数第二位借“1”,相当于得到了(10)2,也就是相当于十进制数中的2,用2减去1得1。
(2)再计算倒数第二位,因为该位同样为“0”,不及减数“1”大,需要继续向倒数第三位借“1”(同样是借“1”当“2”),但因为它在上一步中已借给了最后一位“1”(此时是真实的“1”),则倒数第二位为1,与减数“1”相减后得到“0”。
(3)用同样的方法倒数第三位要向它们的上一位借“1”(同样是当“2”),但同样已向它的下一位(倒数第二位)借给“1”(此时也是真实的“1”),所以最终得值也为“0”。
(4)被减数的倒数第四位尽管与前面的几位一样,也为“0”,但它所对应的减数倒数第四位却为“0”,而不是前面几位中对应的“1”,它向它的高位(倒数第五位)借“1”(相当于“2”)后,在借给了倒数第四位“1”(真实的“1”)后,仍有“1”余,1 –0=1,所以该位结果为“1”。
(5)被减数的倒数第五位原来为“1”,但它借给了倒数第四位,所以最后为“0”,而此时减数的倒数第五位却为“1”,这样被减数需要继续向它的高位(倒数第六位)借“1”(相当于“2”),2–1=1。
(6)被减数的最后一位本来为“1”,可是借给倒数第五位后就为“0”了,而减数没有这个位,这样结果也就是被减数的相应位值大小,此处为“0”。
在二进制数的加、减法运算中一定要联系上十进制数的加、减法运算方法,其实它们的道理是一样的,也是一一对应的。在十进制数的加法中,进“1”仍就当“1”,在二进制数中也是进“1”当“1”。在十进制数减法中我们向高位借“1”当“10”,在二进制数中就是借“1”当“2”。而被借的数仍然只是减少了“1”,这与十进制数一样。
乘法:
把二进制数中的“0”和“1”全部当成是十进制数中的“0”和“1”即可。根据十进制数中的乘法运算知道,任何数与“0”相乘所得的积均为“0”,这一点同样适用于二进制数的乘法运算。只有“1”与“1”相乘才等于“1”。乘法运算步骤:
(1)首先是乘数的最低位与被乘数的所有位相乘,因为乘数的最低位为“0”,根据以上原则可以得出,它与被乘数(1110)2的所有位相乘后的结果都为“0”。
(2)再是乘数的倒数第二位与被乘数的所有位相乘,因为乘数的这一位为“1”,根据以上原则可以得出,它与被乘数(1110)2的高三位相乘后的结果都为“1”,而于最低位相乘后的结果为“0”。
(3)再是乘数的倒数第三位与被乘数的所有位相乘,同样因为乘数的这一位为“1”,处理方法与结果都与上一步的倒数第二位一样,不再赘述。
(4)最后是乘数的最高位与被乘数的所有位相乘,因为乘数的这一位为“0”,所以与被乘数(1110)2的所有位相乘后的结果都为“0”。
(5)然后再按照前面介绍的二进制数加法原则对以上四步所得的结果按位相加(与十进制数的乘法运算方法一样),结果得到(1110)2×(0110)2=(1010100)2。
除法:
(1)首先用“1”作为商试一下,相当于用“1”乘以除数“110”,然后把所得到的各位再与被除数的前4位“1001”相减。按照减法运算规则可以得到的余数为“011”。
(2)因为“011”与除数“110”相比,不足以被除,所以需要向低取一位,最终得到“0111”,此时的数就比除数“110”大了,可以继续除了。同样用“1”作为商去除,相当于用“1”去乘除数“110”,然后把所得的积与被除数中当前四位“0111”相减。根据以上介绍的减法运算规则可以得到此步的余数为“1”。
(3)因为“1”要远比除数“110”小,被除数向前取一位后为“11”,仍不够“110”除,所以此时需在商位置上用“0”作为商了。
(4)然后在被除数上继续向前取一位,得到“110”。此时恰好与除数“110”完全一样,结果当然是用“1”作为商,用它乘以除数“110”后再与被除数相减,得到的余数正好为“0”。证明这两个数能够整除。
这样一来,所得的商(1101)2就是两者相除的结果。
⑦ 计算机二进制转化成十进制的算法步骤是什么
从最低位(最右)算起,位上的数字乘以本位的权重,权重就是2的第几位的位数减一次方。
比如第2位就是2的(2-1次)方,就是2;第8位就是2的(8-1)次方是128。把所有的值加起来。
2(1-1)代表2的0次方,就是1;其他类推
比如二进制1101,换算成十进制就是:1*2(1-1)+0*2(2-1)+1*2(3-1)+1*2(4-1)=1+0+4+8=13
(7)最右算法扩展阅读
计数规则:
在人们使用最多的进位计数制中,表示数的符号在不同的位置上时所代表的数的值是不同的。
十进制(D(decimal))是人们日常生活中最熟悉的进位计数制。在十进制中,数用0,1,2,3,4,5,6,7,8,9这十个符号来描述。计数规则是逢十进一。
二进制(B(binary))是在计算机系统中采用的进位计数制。在二进制中,数用0和1两个符号来描述。计数规则是逢二进一。
十六进制(H(hexadecimal))是人们在计算机指令代码和数据的书写中经常使用的数制。在十六进制中,数用0,1,…,9和A,B,…,F(或a,b,…,f)16个符号来描述。计数规则是逢十六进一。
⑧ 方阵格子从最左上到最右下走法有多少,怎么解决
我数学不好,给个程序吧,而且也不知道算法对不对,你自己检验吧:
#include <stdio.h>
#define COL 2
#define ROW 3
int xx[ROW+2][COL+2]={0};
int fun(int x,int y)
{
int s=0;
int i,j;
xx[x][y]=1;
if (x==ROW && y==COL){
return s+=1;
}
if (xx[x+1][y]!=1){
xx[x+1][y]=1;
s+=fun(x+1,y);
xx[x+1][y]=0;
}
if (xx[x][y+1]!=1){
xx[x][y+1]=1;
s+=fun(x,y+1);
xx[x][y+1]=0;
}
if (xx[x-1][y]!=1){
xx[x-1][y]=1;
s+=fun(x-1,y);
xx[x-1][y]=0;
}
if (xx[x][y-1]!=1){
xx[x][y-1]=1;
s+=fun(x,y-1);
xx[x][y-1]=0;
}
return s;
}
main()
{
int i,j;
for (i=0;i<ROW+2;i++){
xx[i][0]=1;
xx[i][COL+1]=1;
}
for (i=0;i<COL+2;i++){
xx[0][i]=1;
xx[ROW+1][i]=1;
}
printf("%d*%d %d\n",ROW,COL,fun(1,1));
}
TC20编译成功,如果要改变计算的值,只要改一开始的那几个宏定义就好了,ROW代表行数,COL代表列数,以下是几个结果:
1*1 1;
2*2 4;
1*2 2;
3*3 12;
2*3 4;
4*4 184;
..
..
.