蓝桥杯-算法(博主用js实现笔记)


前言

官方地址https://edu.csdn.net/skill/algorithm
蓝桥杯算法,博主以js方式实现,方便前端、及node开发的同学们参考。交流
近期陆续更新…你们当提刷吧,前端工作用的到的,看过去一遍,以后碰到类似需求回来ctrl+f关键字查


2022/05/12博主:知道了,我更新,别私信催别催。。。。

一、基础算法

1.切面条

一根高筋拉面,中间切一刀,可以得到2根面条。
如果先对折1次,中间切一刀,可以得到3根面条。
如果连续对折2次,中间切一刀,可以得到5根面条。
那么,连续对折10次,中间切一刀,会得到多少面条呢?

	1+Math.pow(2,n) // 2的n次方

2.大衍数列

中国古代文献中,曾记载过“大衍数列”, 主要用于解释中国传统文化中的太极衍生原理。它的前几项是:0、2、4、8、12、18、24、32、40、50 …其规律是:对偶数项,是序号平方再除2,奇数项,是序号平方减1再除2。第100 项的值。

	for(var i=1;i<100;i++){
	  if(i%2==0){
	      console.log(Math.pow(i,2)/2)
	  }else{
	      console.log((Math.pow(i,2)-1)/2)
	  }
	}

3.门牌制作

1-2020有多少个2

	//方法一2层for
	var size=0
	for(var i=1;i<=2020;i++){
		(i+"").split("").forEach(val=>{
			if(val=="2"){
				size+=1
			}
		})
	}
	console.log(size)//624个
   //for do while
   var size=0
	for(var i=1;i<=2020;i++){
		var j=i
		while(j>1){ //因为会有0.2020这种值
			if(j%10==2){ //2020%10=2
				size++
			};
			j=parseInt(j/10)//不然乎变成2.020
		}
	}
	console.log(size)//624

3.方阵转置

[[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]]
顺时针旋转90度变成
[[13,9,5,1],
[14,10,6,2],
[15,11,7,3],
[16,12,8,4]]

//新建二维数组
	var Xsize=4;//几*几的矩阵,题目是4*4的矩阵
	var Ysize=4;//几*几的矩阵,题目是4*4的矩阵
	var arr=new Array(); 
	var mun=1;
	for(var i=0;i<Xsize;i++){
		arr[i]=[]
		for(var j=0;j<Ysize;j++){
			arr[i][j]=mun;//二维数组赋值
			mun++
		}
	}
	//执行结果如下
	// [
	// 	[1,2,3,4],
	// 	[5,6,7,8],
	// 	[9,10,11,12],
	// 	[13,14,15,16]
	// ]
	console.log(arr)
	//方阵转置
	var newArr=new Array();//用来存转置后的值的数组
	for(var i=0;i<Ysize;i++){ //博主ps:这里注意,如果是4*3的矩阵,你还是一个变量,就会出现[undefined,undefined,undefined,undefined],因,这样,不管是正方形还是矩形,都没问题了。
		newArr[i]=[]
		for(var j=0;j<Xsize;j++){
			newArr[i][j]=arr[j][i]
		}
	}
	console.log(newArr)
	//转置其实就是 arr[0,3]和arr[3,0]的值互换 也就是二维数组键名 [x,y]的键值等于[y,x]的键值。
	//执行结果如下
	// [
	// 	[1,5,9,13],
	// 	[2,6,10,14],
	// 	[3,7,11,15],
	// 	[4,8,12,16],
	// ]
	//接下去只要将每一行的数值头尾对换,也就是newArr的  [0,0]的值等于[3,0] 的,[1,0]等于[2,0]的值以此类推
	var lastArr=[];
	for(var i=0;i<Ysize;i++){
		lastArr[i]=[]
		for(var j=0;j<Xsize;j++){
			
			lastArr[i][j]=newArr[i][Xsize-j-1]
		}
	}
	console.log(lastArr)

4.微生物增殖

假设有两种微生物 X 和 Y
X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍)
一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y。
现在已知有新出生的 X=10,Y=90,求60分钟后Y的数目。

timem个0.5分xy
001090
0.511090-10=80
121080
1.531080-10=70
241070*2=140
2.5510140-10=130
3610*2=20130
3.5720130-20=110
4820110*2=220
//半分等于0.5分,循环时以0.5为统计单位,要统计120次。 
var x=10;
var y=90;
for(var i=0;i<120;i++){
	if(i%2==1){//x吃y
		y-=x
	}
	if(i%4==0){//y分裂
		y*=2
	}
	if(i%6==0){//x分裂
		x*=2
	}
}
console.log(y)//94371840

5.成绩统计(冒泡法)

小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。
如果得分至少是 60 分,则称为及格。
如果得分至少为 85 分,则称为优秀。
7个同学成绩 80,92,56,74,88,100,0
请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整数。

单科

var arr=[
	80,92,56,74,88,100,0
]
var mun60=0;
var mun85=0;
for(var i=0;i<arr.length;i++){
	if(arr[i]>=60){
		mun60++
	}
	if(arr[i]>=85){
		mun85++
	}
}
var mun60Val=Math.round(mun60*100/arr.length)//逢5进1
var mun85Val=Math.round(mun85*100/arr.length)
console.log("及格率:"+mun60Val+"%,优秀率:"+mun85Val+"%")//及格率:71%,优秀率:43%

多科 (本博主扩展) 以单向链表方法录入数据,以冒泡法求出全班平均分最高和最低的同学。

学号姓名数学语文英语
1小明906070
2小红708085
3小黄707099
4小刚1008560
5小王887750
6小李6075100
//单向链表 方法(别纠结  不想写class)
function list(){
	let m=this;
	//节点
	function Nodes(data){
		this.data=data
		this.next=null;
	}
	m.length=0;
	m.head=null;
	//新增
	list.prototype.append=function(data){
		let newNodes=new Nodes(data);
		let nowData=m.head;
		if(m.head){
			while(nowData.next){ 
				nowData=nowData.next//相当于指针
			}
			nowData.next=newNodes
		}else{
			m.head=newNodes
		}
		m.length++
	}
	//平均成绩最高的小朋友
	list.prototype.maxminFun=function(callback){
		callback=callback||function(){}
		let nowData=m.head;//当前指针位置
		let maxData=m.head;//最大值
		let minData=m.head;//最小值
		while(nowData.next){
			let countA=nowData.data.shuxue+nowData.data.zn+nowData.data.en
			let countB=maxData.data.shuxue+maxData.data.zn+maxData.data.en
			let countC=minData.data.shuxue+minData.data.zn+minData.data.en
			if(countB<countA){//正常3科之和大,平均分就高,所以对比总和就够了,这里哥就不考虑相等的情况了,大家自己扩展
				maxData=nowData
			}
			if(countC>countA){
				minData=nowData
			}
			nowData=nowData.next
		}
		callback(maxData.data.name,minData.data.name)
	}
}
//数据
var ranking=new list();
var rankRes=[
		{id:1,name:"小明",shuxue:90,zn:60,en:70},  //220
		{id:2,name:"小红",shuxue:70,zn:80,en:85},  //235
		{id:3,name:"小黄",shuxue:70,zn:70,en:99},  //239
		{id:4,name:"小刚",shuxue:100,zn:85,en:60}, //245
		{id:5,name:"小王",shuxue:88,zn:77,en:50},  //215
		{id:6,name:"小李",shuxue:60,zn:75,en:100}  //235
]
rankRes.forEach(item=>{//懒
	ranking.append(item)
})
ranking.maxminFun((max,min)=>{
	console.log(`平均成绩最高:`+max,`,最低:`+min)
})
//冒泡法

6.星系炸弹

高斯日记:
大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,
它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日

//这个感觉没必要计算闰年啥的,直接时间戳加减感觉就可以了啊,博主直接上直接的笔记

//获取日期
function getPreDate(pre,date,type) {//pre 向前推几天 type,date有传日期就从data日期开始推, 如果是true 就赛选返回那天的前一天 59分59秒
  var c = new Date();
  if(date){
      c=new Date(date)
  }
  c.setDate(c.getDate() - pre);
  if(type){
      return formatDate(c)+" 23:59:59"
  }else{
     return formatDate(c);
  }
}
function formatDate(d) {
 
  return d.getFullYear() + "-" + getMonth(d.getMonth()) + "-" + getMonth(d.getDate(), "getDate")
}
function getMonth(m,type) {
  if (type != "getDate") {
    m++;
  }
  if (m < 10)
    return "0" + m.toString();
  return m.toString();
}
var today= getPreDate(0)//今天日期 "2022-04-27"
var tomorrow= getPreDate(-1)//明天日期 "2022-04-28"
var yesterday= getPreDate(1)//昨天日期 "2022-04-28"

var day5343=getPreDate(-(5343-1),"1777-04-30")//"1791-12-15"
var day8113=getPreDate(-(8113-1),"1777-04-30")//"1799-07-16"

7.特别数的和

小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),
在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。
请问,在 1 到 n 中,所有这样的数的和是多少?

//博主ps,这题要注意看,像13 14,这里面十位数是1,也就是 13和14也是要算进去的,23 24.十位数是2也要算进去。

var x=40;
var count=0
for(var i=1;i<=x;i++){
	if(whileFun(i)){
		count+=i
	}
}
function whileFun(val){
	while(val>0){
		var theVal=val%10;
		if(theVal==0||theVal==1||theVal==2||theVal==9){
			return true;
		}
		val=parseInt(val/10)
	}
	return false;
}

8.蛇形填数

如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 …
3 5 8 14 …
4 9 13 …
10 12 …
11 …

容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?

//算法一
如果光算 {20,20}的值很简单
//{0,0}{1,1}{2,2}{3,3}{4,4}{5,5}分别对应  1 5 13 25 41 61
//两两差值为 4 8 12 16 20为4的倍数
//差值为4*1 4*2 4*3
var n=20-1;//20-1   
var val=1;//{0,0}开始 加  {20,20} 是加了19次
for(var i=1;i<=n;i++){
	val+=4*i;
}
console.log(val)//20行20列为  761

蛇形三角

//算法二,博主自己想的逻辑。 主要是解决  {10,15}这种不等的坐标值
//{x,y}
	// {0,0} {1,0} {2,0} {3,0}   	1 2 6 7      
	// {0,1} {1,1} {2,1}        	3 5 8
	// {0,2} {1,2}              	4 9
	// {0,3}						10
	var numX=20; //(这是X轴,记得减1才是坐标)20排20列坐标是 {19,19}数组{0,0}开始算的
	var numY=20; //(这是Y轴)记得减1才是坐标)20排20列坐标是 {19,19}数组{0,0}开始算的
	var val=1;
	var arr=[]
	var x=0;y=0;
	var gosize=0;
	var isPlay=true
	while(isPlay){
		if(!arr[y]){
			arr[y]=[]
		}
		arr[y][x]=val;
		if(x==(numX-1) &&y==(numY-1)){
			isPlay=false;
			break;
		}
		if(y==0){//
			if(gosize==0){
				x++
				gosize++
			}else if(gosize==1){
				y++;
				x--
			}else if(gosize==-1){
				x++
				gosize=1
			}
		}else if(x==0){
			if(gosize==1){
				y++
				gosize--
			}else if(gosize==0){
				x++
				y--
				gosize--
			}
		}else if(gosize==-1){
			x++
			y--
		}else if(gosize==1){
			x--
			y++
		}
		
		val++;
	}
	console.log(arr[y][x])//761
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪狼之夜

打个赏,让博主知道博文没白写

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值