传智杯第一届 真题解析 Java

例题一

从古至今,各种末日谣言层出不穷。假如现在有这样一个谣言:天文学家在2014年6月1日,发现一颗行星,根据该行星的运行轨道,在3000天以后,该行星将撞击地球。现在,请编写Java程序计算,该谣言指向的“世界末日”是哪一天?

要求输出格式为:xxxx-xx-xx(例如:2015-12-12),不要添加任何其他多余文字。

输出描述:
计算的结果日期,格式为:xxxx-xx-xx


输出样例:
2015-12-12

思路

一开始我想硬算发现有点麻烦,然后看了下大佬的题解,才晓得
还有Data类,记住了

大佬链接

import java.util.Calendar;
import java.util.Date;

public class Answer1 {
	public static void main(String[] args) {
		int year=2014;//date的输出为1900年到现在的年数,因此需要具体年份时需要+1900
		int month=6;//需要注意,在调用calendar或date类的方法时,输入或输出的月份均为0-11
		int day=1;
		int add=3000;
		
		//1.调用calendar的add方法
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month-1, day);
		calendar.add(Calendar.DATE, add);
		System.out.println(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1)
				+"-"+calendar.get(Calendar.DATE));
		
		//2.直接用calendar设置增加后的日,进行输出
		Calendar calendar1 = Calendar.getInstance();
		calendar1.set(year, month-1, day+add);
		System.out.println(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1)
				+"-"+calendar.get(Calendar.DATE));
		
		//3.直接用calendar设置增加后的日,再调用date格式化
		Date date = new Date(year, month-1, day+add);
		System.out.println(date.getYear()+"-"+(date.getMonth()+1)+"-"+date.getDate());
	}
}

答案:2015-12-01

例题二

由1到n的平方个数字组成的n×n阶方阵(n为任意给定的一个不小于3的奇数),它的每行、每列及对角线上的数字和都相等,称为n阶魔方阵。它的每行、每列及对角线上的数字和为n×(n² + 1) / 2。该方阵的排列方法是:

(1) 将数字1放在第一行的中间位置上,即(0,n/2)位置;
(2) 下一个数放在当前位置(i, j)的上一行(i-1)、下一列(j+1),即当前位置的右上方;如果出现以下情况,则修改填充位置:
① 若当前位置是第一行,下一个数放到最后一行,即把i-1修改为n-1;
② 若当前位置是最后一列,下一个数放在第一列,即把j-1修改为n-1;
③ 若下一个数要放的位置已经有数字,则下一个数放在当前位置的下一行,相同列。
(3) 重复以上过程,直到n²个数字不重复的填入方阵中。
根据以上描述,请使用Java语言,设计一个程序,输出n阶魔方阵。

输入描述:

一个大于等于3的奇数n,不建议太大,3-9即可

输出描述:

一个n*n的数字矩阵,每行的数字之间采用一个制表符"\t"分隔

输入样例:
3
输出样例:
8 1 6
3 5 7
4 9 2
无脑照题目模拟一下,写完之后看大佬写的,发现其实
整个就是:下一个数在当前数的右上方,如果超出了正方
形范围就取摸,如果右上方有数字已经放了,就放在当
前数的正下方

无脑模拟

package 传智杯第一届;

import java.util.Scanner;

public class No2 {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        int n=input.nextInt();
        int [][]arr=new int[n][n];
        int j=(n/2);
        int i=0;
        for(int m=1;m<=n*n;m++){
            arr[i][j]=m;
            /*
             下一个数放在当前位置(i, j)的上一行(i-1)、下一列(j+1),即当前位置的右上方;如果出现以下情况,则修改填充位置:
              若当前位置是第一行,下一个数放到最后一行,即把i-1修改为n-1;
             */

            if(i==0&&arr[n-1][(j+1+n)%n]==0){
                i=n-1;
                j=(j+1+n)%n;

            }
            //②若当前位置是最后一列,下一个数放在第一列,即把j-1修改为n-1;
           else if(j==n-1&&arr[(i-1+n)%n][0]==0){
                i=(i-1+n)%n;
                j=0;
            }
           //③ 若下一个数要放的位置已经有数字,则下一个数放在当前位置的下一行,相同列。
           else if(arr[(i-1+n)%n][(j+1+n)%n]!=0){
               i=(i+1+n)%n;

            }
           else {
                i=(i-1+n)%n;
                j=(j+1+n)%n;
            }
        }
        for(int m=0;m<n;m++){
            for(int k=0;k<n;k++){
                System.out.print(arr[m][k]+"\t");
            }
            System.out.println();

        }
    }
}

大佬简易代码

import java.util.Scanner;

public class Answer2 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n=sc.nextInt();
		int num[][]=new int[n][n];
		int i=0;
		int j=n/2;
		int k=1;
		while(k<=n*n){
			if (num[i][j]==0) {
				num[i][j]=k++;
				i=(i-1+n)%n;
				j=(j+1+n)%n;
			}else {
				i=(i+1+n)%n;
			}
		}
		for (i = 0; i < n; i++) {
			for(j=0;j<n;j++){
				System.out.print(num[i][j]+"\t");
			}
			System.out.println();
		}
	}
}

例题三

从前,某国王在处决500名死囚犯时突发奇想,想赦免其中的一个人,于是他把这500个死囚犯从1到500编号,都放到一片空地上,让大家手牵手组成一个大环。从1号开始报数,凡是报数为3的倍数的人就要被杀掉,每轮过后,剩下的人组成一个较小的环,继续报数(注意,上一轮最后一人报数后,下一轮的第一个人要继续往下报,而不是重新从1开始),直到剩下最后一个人为止。请编写程序计算,最终这个幸运的人是几号?

输出描述:

一个整数,表示最终活下来的人员编号

输出样例:

55

思路阿瑟夫环问题

import java.util.Scanner;

public class No3{
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);

        int n=500;
        int m=3;
        int res=0;

        for(int i=2;i<=n;i++){
            res=(res+m)%i;
        }
        System.out.println(res+1);
}
}

答案:436

例题四

给定一个正整数m(m最小是一个两位数),现在想从组成m这个数的数字中,去掉其中的n个数字(0 < n < m的位数),但保持每位上的数字相对顺序不变,使得剩余的数字组成的数是最大值。例如:
当m = 51342,n = 1;则结果应该是去掉数字1,剩余的值最大,为5342;
当m = 51342,n = 2;则结果应该是去掉数字1、3,剩余的值最大,为542;
当m = 51342,n = 3;则结果应该是去掉数字1、3、2,剩余的值最大,为54;

请使用Java语言编程,实现该算法。其中的m和n按要求输入正确范围内的数字即可,无需做合法校验。

输入描述:
第一行输入正整数m(m >= 10)
第二行输入去掉的数字个数n(0 < n < m的位数)
输出描述:
去掉n个数字后的最大值

输入样例:
51342
2
输出样例:
542

思路:

dfs 递归实现组合型枚举 类似于给定一个数,从中从前往后
选取n个数,凑成一个新的数,求这个数的最大值
import java.util.Scanner;

public class No4 {
    static int Max=-1;
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        String m=input.next();
        int n=input.nextInt();
        char []temp=m.toCharArray();
        int nn=m.length()-n;
        int []vis=new int[nn];
        String []arr=new String[nn];
        dfs(arr,nn,0,temp,0);
        System.out.println(Max);


    }
    public static void dfs(String []arr,int n,int level,char []temp,int next){
        if(level>=n){
            String tempsum="";
            for(int i=0;i<n;i++){
                tempsum+=arr[i];

            }
            int sum=Integer.parseInt(tempsum);
            if(sum>Max)
                Max=sum;

            return;
        }
        for(int i=next;i<temp.length;i++ ){
            arr[level]=temp[i]+"";
            dfs(arr,n,level+1,temp,i+1);

        }


    }
}

例题五

小智拿到一个数列{a1, a2, …, an},现在他想从这个数列中取出若干数,组成一个新的数列{ai1, ai2, …, aim},其中索引i1, i2, …, im保持递增,也就是说数列中各个数仍然保持在原数列中的先后顺序。并且在新数列中,对于任意索引ix > iy,都有aix > aiy,也就是说新数列是一个递增的子序列。

请编写程序,求出符合上述要求的最长递增子序列的长度。

例如数列[1, 3, 6, 7, 9, 4, 10, 5, 6],最长递增子序列为[1, 3, 6, 7, 9, 10],长度是6。

输入描述:

任意个数的整数,中间使用空格分隔
输出描述:

一个整数,表示符合题目要求的最长子序列的长度

输入样例:

1 3 6 7 9 4 10 5 6

输出样例:

6

思路

简单的dp,最长上升子序列问题

import java.util.Scanner;

public class No5 {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        String In=input.nextLine();
        String arrtemp[]=In.split("\\s+");
        int n=arrtemp.length;
        int []arr=new int[n+1];
        int []dp=new int[n+1];
        for(int i=0;i<n;i++){
            arr[i]=Integer.parseInt(arrtemp[i]);
        }
        int ans=0;
        for(int i=0;i<n;i++){
            dp[i]=1;
            for(int j=0;j<i;j++){
                if(arr[i]>arr[j])
                    dp[i]=Math.max(dp[i],dp[j]+1);

            }
            ans=Math.max(dp[i],ans);
        }
        System.out.print(ans);
    }
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值