例题一
从古至今,各种末日谣言层出不穷。假如现在有这样一个谣言:天文学家在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);
}
}