【第十届蓝桥杯Java B组】不同子串&数列求值&数的分解


2019蓝桥杯题目

不同子串

  1. 问题描述

【问题描述】
一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成 的串。例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共 7 个。 注意在计算时,只算本质不同的串的个数。 请问,字符串0100110001010001 有多少个不同的非空子串?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
3. 思路分析
使用用hashset,如果有重复的字符串会覆盖之前的字符串,最后用size()求出集合中字符串的个数
知识点补充:
【Java】String类substring() 方法

  1. 代码
package 不同子串;

import java.util.HashSet;
import java.util.Set;

public class Main {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
       String s ="0100110001010001";
       Set<String> set = new HashSet<String>();
       for(int i=0;i<s.length();i++) {
    
    
    	   for(int j=i+1;j<=s.length();j++) {
    
    
    		   String t = s.substring(i, j);
    		   set.add(t);
    	   }
       }
       System.out.println(set.size());
	}

}

  1. 答案:100

数列求值

  1. 问题描述

【题目描述】:

给定数列 1, 1, 1, 3, 5, 9, 17, …,从第 4 项开始,每项都是前 3 项的和。求第 20190324 项的最后 4 位数字
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个 4 位整数(提示:答案的千位不为 0),在提交答案时只填写这个整数,填写多余的内容将无法得分

  1. 思路分析

① 一开始的时候没有想到使用取余数的方法,实在是太笨了,假如需要某个数字的末尾几位那么只需要将这个数字取这相应位数大1的数字即可,比如这道题目是需要取出末尾四位数字那么只需要对10000取余数即可,因为任何大于10000的数字取余之后那么结果都会在0~9999之间所以自然就可以得到末尾的四位数字,不管怎么样取余数那么结果对于某位四位数字是没有任何影响的

② 因为要求解出第20190324项,所以其中的数字还是比较大的,可以使用四个变量来记录中间结果,在循环的时候对这四个数字进行动态改变,并且在计算之前需要对每个中间结果进行取余,确保当前记录的变量在10000以下

  1. 代码
#include<stdio.h>
int main(){
    
    
	int i;
    int a=1,b=1,c=1,t;
	for(i=4;i<=20190324;i++){
    
    
		t=(a+b+c)%10000;
		a=b;
		b=c;
		c=t;
	}
	printf("%d",c);
	return 0;
}

4.答案:4659

数的分解

  1. 问题描述
    【问题描述】
    把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法?注意交换 3 个整数的顺序被视为同一种方法,例如 1000+1001+18 和1001+1000+18 被视为同一种。
    【答案提交】
    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分

  2. 思路分析

  • 暴力三重循环,三个数进行排列组合有6种方法,所以结果除以6,
    因为2000以上的数包含2,所以循环到2000就行了
  • 仔细一想可以使用两层循环可以搞定,因为第三个数字可以使用2019减去其余的两个数字得到从而省略运行时间,并且因为需要排除重复,所以第二层循环的变量需要比第二层循环的变量大一,第三层循环的变量需要比第二层循环的变量也是大一,因为在第一层循环的时候的使用当前的变量尝试了所有结果,所以第二层循环应该比第一层循环大一的基础上进行,第三层循环也是如此,这样的话可以排除重复的方案
    更省时间和简单详见看https://blog.csdn.net/qq_39445165/article/details/104660063
  1. 代码
    这里写的是三重循环的方法(一开始判断是否包含2或4的方法写复杂了…看别人写的用一个while直接搞定)
#include<stdio.h>
/*
int check(int n){
	if(n<10){
		if(n==2 || n==4){
			return 0;
		}
	}
	else if(n<100){
		if(n%10==2 || n%10==4 || n/10==4 || n/2==4){
			return 0;
		}
	}
	else if(n<1000){
		if(n/100==2||n/100==4){
			return 0;
		}
		else{
			return check(n%100);
		}
	}
	else if(n<2000){
		if(n/1000==2||n/1000==4){
			return 0;
		}
		else{
			return check(n%1000);
		}
	}
	return 1;
}*/
int check(int n){
    
    
    while(n){
    
    
          if(n%10==2||n%10==4){
    
    
              return 0;
          }
          n/=10; 
     }
    return 1;
}
int main(){
    
    
	int i,j,k,count=0;
	for(i=1;i<2000;i++){
    
    
		if(check(i)==0)
		   continue;
			for(j=1;j<2000;j++){
    
    
				if(check(j)==0 || i==j)
				   continue;
					for(k=1;k<2000;k++){
    
    
						if(i==k ||j==k ||check(k)==0)
						  continue;
			         	if(i+j+k==2019){
    
    
					        count++;
			       	   }
		      	}	
		}
		
	}
	printf("%d",count/6);
	return 0;
}
  1. 答案:40785

猜你喜欢

转载自blog.csdn.net/weixin_45867159/article/details/114085010