第一届蓝桥杯国际赛真题 试题BC

试题B:网站扩张


这道题我用到了递归算法,代码含义都下边代码的注释里,不再多做解释。
在这里插入图片描述

代码实现

	//递归方法
	public int people(int n) {//n为天数
		int b=1;//用户个数
		for (int i = 1; i <= n; i++) {
			if(n>7) {//若n<=7,即前七天用户一直是一个,七天之后才开始改变
				/*
				 * 由题可知在此用户使用前七天之后的每一个七天的第一天,第四天,和第七天都会增加一个用户,
				 * 这里当增加用户时b+1且进行递归,递归中的天数为从这个新用户使用开始到n的天数而不是n
				 */
				if(i%7==1||i%7==4||i%7==0) {
					 b += 1;
					people(n-i);
				}
			}
		}
		return b;
	}

试题C:基因配对


这道题应该用到字符串的模式匹配,由于普通的模式匹配算法在字符串过长时运行时间长,为了追求快速匹配,我这里用了模式匹配的KMP算法。下面是我学习KMP算法过程中参考的视频:

算法解析

代码实现

字符串在Java中是不可变的,但是为了把模式串的ATCG替换为TAGC,可以使用StringBuilder:

StringBuilder strb = new StringBuilder(S);
strb.setCharAt(i, 'A');

在这里插入图片描述
在这里插入图片描述
代码实现

public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		String L=scanner.nextLine();//主串
		String S=scanner.nextLine();//模式串
		//因为是基因配对,所以先把模式串的ATCG改为TAGC
		StringBuilder strb = new StringBuilder(S);
		for (int i = 0; i < S.length(); i++) {
			if (S.charAt(i)=='A') {
				strb.setCharAt(i, 'T');
			}else if (S.charAt(i)=='T') {
				strb.setCharAt(i, 'A');
			}else if (S.charAt(i)=='C') {
				strb.setCharAt(i, 'G');
			}else if (S.charAt(i)=='G') {
				strb.setCharAt(i, 'C');
			}
		}
		
		int index=KMP(L, strb);//调用KMP算法方法得到索引
		System.out.println(index+1);//输出位置
	}
	//KMP算法方法
	public static int KMP(String L,StringBuilder subStr) {
		//计算next数组
		int[]next=getNext(subStr);
		//定义一个指针,用于指向主串中的第一个字符
		int x=0;
		//定义一个指针,用于指向模式串中的第一个字符
		int y=0;
		//循环实现字符串的匹配操作
		while (x<L.length()&&y<subStr.length()) {
			if(y==-1||L.charAt(x)==subStr.charAt(y)) {
				x++;
				y++;
			}else {
				y=next[y];
			}
		}
		
		if(y==subStr.length()) {
			return x-y;
		}else {
			return -1;
		}
	}
	
	//得到next数组的方法
	public static int[] getNext(StringBuilder subStr) {
		//定义一个next数组
		int[] next=new int[subStr.length()];
		//设置next数组的第一个元素值为-1
		next[0]=-1;
		//设置两个元素y和len,y指匹配失败时模式串的索引,len指当前最大前后缀长度
		int y=0,len=-1;
		//定义一个循环,用于计算next数组
		while (y<subStr.length()-1) {
			if (len==-1||subStr.charAt(y)==subStr.charAt(len)) {
				y++;
				len++;
				next[y]=len;
			}else {
				len=next[len];
			}
		}
		return next;
	}
	
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值