第九届蓝桥杯大赛软件类省赛Java大学B组

一、第几天

标题:第几天

2000年的1月1日,是那一年的第1天。 那么,2000年的5月4日,是那一年的第几天?

注意:需要提交的是一个整数,不要填写任何多余内容。

【答案】:125

【解析】:2000年是闰年(能被400整数,2月29天),31 + 29 + 31 + 30 + 4 == 125

二、方格计数

标题:方格计数

如图p1.png所示,在二维平面上有无数个1x1的小方格。

p1.png

我们以某个小方格的一个顶点为圆心画一个半径为1000的圆。 你能计算出这个圆里有多少个完整的小方格吗?

注意:需要提交的是一个整数,不要填写任何多余内容。

【答案】:3137548

分析:

完整的方格,找圆中最大的矩形长宽没思路,那就找以(0,0)为起点,以非零为终点的方格,方格的对角线要小于半径,利用勾股定理,或者圆的标准方程,x² * y² =z²

顶点不能再坐标轴上,也就是x和y不能为0

四个象限,只找一个象限的顶底个数,然后*4

代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int k=0;
        int n=sc.nextInt();
        for(int i=1;i<=n;i++){          //注意长宽不能为0,不能再坐标轴上
        	for(int j=1;j<=n;j++){
        		if((i*i+j*j)<=n*n){     //求三角形的最大边的长度,如果小于半径的平方,那就是在圆内
        			k++;
        		}
        	}
        }
        System.out.print(k*4);     //四个象限,4个不同位置
    } 
}

在这里插入图片描述

三、复数幂

标题:复数幂

设i为虚数单位。对于任意正整数n,(2+3i)^n 的实部和虚部都是整数。 求 (2+3i)^123456 等于多少?
即(2+3i)的123456次幂,这个数字很大,要求精确表示。

答案写成 “实部±虚部i”
的形式,实部和虚部都是整数(不能用科学计数法表示),中间任何地方都不加空格,实部为正时前面不加正号。(2+3i)^2 写成: -5+12i,
(2+3i)^5 的写成: 122-597i

注意:需要提交的是一个很庞大的复数,不要填写任何多余内容。

【答案】:将答案输出到文件,文件大小为135KB,此处不再叙述。

在这里插入图片描述
在这里插入图片描述

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.math.BigInteger;

public class 复数幂文件流 {
	public static void main(String[] args) {
        //Scanner sc=new Scanner(System.in);
    	try{
    		PrintStream ps =new PrintStream(new FileOutputStream("D://fushu.txt")); 
    		System.setOut(ps);   // 文件输出 用System.out.println()即可将内容输出到文件中
    		
    		BigInteger a=new BigInteger("2");  //实部
    		BigInteger b=new BigInteger("3");  //虚部
    		BigInteger x=new BigInteger("2");  //实部
    		BigInteger y=new BigInteger("3");  //虚部
    		
    		for(int i=1;i<123456;i++){
    			BigInteger t=x;
    			x=x.multiply(a).subtract(y.multiply(b)); //实部
    			y=t.multiply(b).add(y.multiply(a));    //虚部
    		}
    		if(y.compareTo(BigInteger.ZERO)>0){
    			System.out.print(x+"+"+y+"i");
    		}else{
    			System.out.print(x+""+y+"i");
    		}   		
    	}catch(Exception e) {
			e.printStackTrace();
    	}
    } 
}

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {	
	public static void main(String arg[]) throws FileNotFoundException{
		PrintStream file=new PrintStream(new FileOutputStream("D:\\test.txt"));
		System.setOut(file);
		Scanner sc=new Scanner(System.in);
		BigInteger a=new BigInteger("2");
		BigInteger b=new BigInteger("3");
		BigInteger x=new BigInteger("2");
		BigInteger y=new BigInteger("3");
		for(int i=2;i<=123456;i++){
			BigInteger shibu,xubu;
			shibu=(x.multiply(a)).subtract((y.multiply(b)));
			xubu=(x.multiply(b)).add(y.multiply(a));
			x=shibu;
			y=xubu;
		}
		System.out.print(x+""+(y.compareTo(BigInteger.ZERO)>0?"+":"")+y+"i");
	}
}

六、递增三元组

标题:递增三元组

给定三个整数数组 A = [A1, A2, … AN], B = [B1, B2, … BN], C = [C1, C2,
… CN], 请你统计有多少个三元组(i, j, k) 满足:

  1. 1 <= i, j, k <= N
  2. Ai < Bj < Ck

【输入格式】 第一行包含一个整数N。 第二行包含N个整数A1, A2, … AN。 第三行包含N个整数B1, B2, … BN。
第四行包含N个整数C1, C2, … CN。

对于30%的数据,1 <= N <= 100 对于60%的数据,1 <= N <= 1000 对于100%的数据,1 <= N <=
100000 0 <= Ai, Bi, Ci <= 100000

【输出格式】 一个整数表示答案

【输入样例】 3 1 1 1 2 2 2 3 3 3

【输出样例】 27

资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。 主类的名字必须是:Main,否则按无效代码处理。

分析:

从小到大排序,
以b数组为中心,查找符合条件的a数组元素有几个,c数组元素有几个,然后相乘,最后相加

注意count可能int装不下,用long类型表示

count相加的时候,要保证相加的数精度不丢失,把1L放在前面相乘

暴力法,ac80%,拿不到满分:

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
    	int n=sc.nextInt();
    	int[] a=new int[n];
    	int[] b=new int[n];
    	int[] c=new int[n];
    	for(int j=0;j<n;j++){
			a[j]=sc.nextInt();
		}
    	for(int j=0;j<n;j++){
			b[j]=sc.nextInt();
		}
    	for(int j=0;j<n;j++){
			c[j]=sc.nextInt();
		}
    	Arrays.sort(a);Arrays.sort(b);Arrays.sort(c);
    	int count=0;
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			if(b[j]<=a[i]){
    				continue;
    			}else{
    				for(int k=0;k<n;k++){
    					if(c[k]>b[j]){
    						count+=n-k;
    						break;
    					}
    				}
    			}
    		}
    	}
    	System.out.print(count);
    }
}

满分ac,优化后算法:

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
    	int n=sc.nextInt();
    	int[] a=new int[n];
    	int[] b=new int[n];
    	int[] c=new int[n];
    	for(int j=0;j<n;j++){
			a[j]=sc.nextInt();
		}
    	for(int j=0;j<n;j++){
			b[j]=sc.nextInt();
		}
    	for(int j=0;j<n;j++){
			c[j]=sc.nextInt();
		}
    	Arrays.sort(a);Arrays.sort(b);Arrays.sort(c);
    	int j=0,k=0;
    	long count=0L;                //   测试的数据类型很大,count可能int保存不下,如果用int不能完全ac
    	for(int i=0;i<n;i++){              //  以b数组为中心,将满足的a数组和c数组相乘
    		while(j<n&&a[j]<b[i]){
    			j++;
    		}
    		while(k<n&&c[k]<=b[i]){
    			k++;
    		}
    		count+=1L*j*(n-k);      //  1L 放在后面的话(j*(n-k)*1L)编译不通过,可能是因为j*(n-k)已经很大,
    		                         //  int保存丢失了精度,所以要把1L放在前面,先变成long

    	}
    	System.out.print(count);
    }
}

import java.util.Arrays;
import java.util.Scanner;
public class Main {	
	public static void main(String arg[]){
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int[] a=new int[n];
		int[] b=new int[n];
		int[] c=new int[n];
		for(int i=0;i<n;i++){
			a[i]=sc.nextInt();
		}
		for(int i=0;i<n;i++){
			b[i]=sc.nextInt();
		}
		for(int i=0;i<n;i++){
			c[i]=sc.nextInt();
		}
		Arrays.sort(a);Arrays.sort(b);Arrays.sort(c);
		long ans=0L;
		int left=0,right=0;
		for(int i=0;i<n;i++){
			while(left<n){
				if(a[left]<b[i]){
					left++;
				}else{
					break;
				}
			}
			while(right<n){
				if(c[right]>b[i]){
					break;
				}else{
					right++;
				}
			}
			ans+=1L*left*(n-right);   //这里也很狗,如果没乘以1L,满分不了。因为left*(n-right)也是有可能超过int范围的。
		}
		System.out.print(ans);
	}
}

七、螺旋折线

标题:螺旋折线

如图p1.png所示的螺旋折线经过平面上所有整点恰好一次。
在这里插入图片描述
对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。

例如dis(0, 1)=3, dis(-2, -1)=9

给出整点坐标(X, Y),你能计算出dis(X, Y)吗?

【输入格式】 X和Y

对于40%的数据,-1000 <= X, Y <= 1000 对于70%的数据,-100000 <= X, Y <= 100000
对于100%的数据, -1000000000 <= X, Y <= 1000000000

【输出格式】 输出dis(X, Y)

【输入样例】 0 1

【输出样例】 3

资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。

分析:找规律+结合坐标点

一共有四个方向,上下左右,每个方向的长度都是等差数列
上:2 4 6 8…
下:1 3 5 7 …
左:1 3 5 7 …
右:2 4 6 8…

判断点(X,Y)在上下左右哪个方向上,然后将各个方向的总和相加

代码:

	import java.util.Scanner;
	
	public class Main {
		
	    public static void main(String[] args) {
	        Scanner sc=new Scanner(System.in);
	    	long x=sc.nextLong(),y=sc.nextLong();
	    	long ans=0;
	    	if(y>0&&Math.abs(x)<=y){                 //上
	    		ans=sum(1,y,2)+sum(1,y,2)+sum(2,y-1,2)+sum(2,y-1,2)+x-(-y);
	    	}else if(y<=0&&x>=y-1&&x<=Math.abs(y)){  //下
	    		ans=sum(1,Math.abs(y),2)+sum(2,Math.abs(y),2)+sum(2,Math.abs(y),2)+sum(1,Math.abs(y),2)+Math.abs(y)-x;
	    	}else if(x>0&&Math.abs(y)<=x){           //右
	    		ans=sum(1,x,2)+sum(1,x,2)+sum(2,x,2)+sum(2,x-1,2)+x-y;
	    	}else if(x<0&&y>=x+1&&y<=Math.abs(x)){   //左
	    		ans=sum(2,Math.abs(x)-1,2)+sum(2,Math.abs(x)-1,2)+sum(1,Math.abs(x),2)+sum(1,Math.abs(x)-1,2)+y-(x+1);
	    	}
	    	System.out.print(ans);
	    }
	    public static long sum(long a1,long n,long d){
	    	return n*a1+((n*(n-1))/2)*d;
	    }
	}

八、日志统计

标题:日志统计

小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有N行。其中每一行的格式是:

ts id

表示在ts时刻编号id的帖子收到一个"赞"。

现在小明想统计有哪些帖子曾经是"热帖"。如果一个帖子曾在任意一个长度为D的时间段内收到不少于K个赞,小明就认为这个帖子曾是"热帖"。

具体来说,如果存在某个时刻T满足该帖在[T, T+D)这段时间内(注意是左闭右开区间)收到不少于K个赞,该帖就曾是"热帖"。

给定日志,请你帮助小明统计出所有曾是"热帖"的帖子编号。

【输入格式】 第一行包含三个整数N、D和K。 以下N行每行一条日志,包含两个整数ts和id。

对于50%的数据,1 <= K <= N <= 1000 对于100%的数据,1 <= K <= N <= 100000 0 <= ts
<= 100000 0 <= id <= 100000

【输出格式】 按从小到大的顺序输出热帖id。每个id一行。

【输入样例】 7 10 2 0 1 0 10 10 10 10 1 9 1 100 3 100 3

【输出样例】 1 3

资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。

分析:

跟2019年第十届的外卖优先级有点相似。
创建二维不定长数组
ArrayList的排序用Collections类


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
    	int n=sc.nextInt(),d=sc.nextInt(),k=sc.nextInt();
    	ArrayList<Integer>[] p=new ArrayList[100001];    // 定义列不定长的二维数组 ,行表示id,列用来添加时间
    	
    	for(int i=0;i<100001;i++){
    		p[i]=new ArrayList<Integer>();
    	}
    	
    	for(int i=0;i<n;i++){
    		int ts=sc.nextInt();
    		int id=sc.nextInt();
    		p[id].add(ts);
    	}
    	ArrayList<Integer> ids=new ArrayList<Integer>();  //定义不定长数组ids保存d秒内不少于k点赞的帖子编号id
    	for(int i=0;i<100000;i++){
    		Collections.sort(p[i]);     //对每组id的ts排序
    		for(int j=0;j<p[i].size();j++){
    			int q=j,count=0;
    			while(q<p[i].size()&&p[i].get(q)<d+p[i].get(j)){
    				q++;count++;    
    			}
    			if(count>=k){
    				ids.add(i);
    				break;
    			}
    		}
    	}
    	Collections.sort(ids);     //ArrayList的排序用collections类
    	for(int i=0;i<ids.size();i++){
    		System.out.print(ids.get(i)+" ");
    	}
    	//System.out.println(ids.get(1));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值