蓝桥杯练习题——java

基础练习

回形取数

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
  回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。
输入格式
  输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。
输出格式
  输出只有一行,共mn个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。
样例输入
3 3
1 2 3
4 5 6
7 8 9
样例输出
1 4 7 8 9 6 3 2 5
样例输入
3 2
1 2
3 4
5 6
样例输出
1 3 5 6 4 2

解题思路:刚开始我想dfs能过,所以用递归写了个dfs,结果如果n和m的数太大,报错;在找不到错误的前提下,改变思路,用的直接遍历,在while循环中进行输出,设左边边界值l=0,右边边界值r=n-1;上边边界值u=0;下边边界值d=m-1;然后,在while循环中使用4个for循环,遍历,一次循环之后,缩小边界,遍历之后,记录;

import java.io.PrintWriter;
import java.util.Scanner;

public class Main {
	static Scanner sc = new Scanner(System.in);
	static int n,m;
	static boolean[][] vis;
	static int[][] ch;
	static PrintWriter out=new PrintWriter(System.out);
	public static void main(String[] args) {
		m=sc.nextInt();
		n=sc.nextInt();
		ch=new int[m][n];
		vis=new boolean[m][n];
		for(int i=0;i<m;i++) {
			for(int j=0;j<n;j++) {
				ch[i][j]=sc.nextInt();
			}
		}
		int l=0,r=n-1,u=0,d=m-1;
		while(true) {
			if(l>r||d<u) {
				break;
			}
			for(int i=u;i<d;i++) {
				if(!vis[i][l]) {
					vis[i][l]=true;
					out.print(ch[i][l]+" ");
				}	
			}
			for(int i=l;i<r;i++) {
				if(!vis[d][i]) {
					vis[d][i]=true;
					out.print(ch[d][i]+" ");
				}
			}
			for(int i=d;i>u;i--) {
				if(!vis[i][r]) {
					vis[i][r]=true;
					out.print(ch[i][r]+" ");
				}
				
			}
			for(int i=r;i>l;i--) {
				if(!vis[u][i]) {
					vis[u][i]=true;
					out.print(ch[u][i]+" ");
				}
			}
			l++;
			d--;
			r--;
			u++;
//			System.out.println((l>r||d<u));
			
		}
		if(n==m&&n%2!=0) {
			out.print(ch[(n-1)/2][(n-1)/2]);
		}
		out.flush();
		out.close();
	}
}

完美的代价

问题描述
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)
输入格式
  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
  第二行是一个字符串,长度为N.只包含小写字母
输出格式
  如果可能,输出最少的交换次数。
  否则输出Impossible
样例输入
5
mamad
样例输出
3

解题思路:while循环处理,大致思路就是从两边开始搜,进行判断过的就可以不要了,因为String没有提供直接删除的方法,在遍历的话,会浪费时间,我觉得。因为字符串长度只有800,可以使用链表存起来,删除也比较方便,首先进行判断n可能为奇也可能偶,若为偶,则如果某个字符只出现一个,则不可能变成一个完美的回文串,若为奇,则不可能大于1;其余则按正常情况进行计算:
1.贪心的思路为:交换之后其余字符串的顺序不变;即可直接删除,交换次数加上应该交换的距离;
2.若为单个字符,n为奇数时:用(n-1)/2-当前字符在原字符中的位置的绝对值;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;

public class Main {
	static Scanner sc = new Scanner(System.in);
	static PrintWriter out=new PrintWriter(System.out);
	public static void main(String[] args) {
		int n=sc.nextInt();
		String str=sc.next();
		LinkedList<Character> list=new LinkedList<Character>();
		for(int i=0;i<n;i++) {
			list.add(str.charAt(i));
		}
		int res=0;    //记录单个的
		int ans=0;
		int key=-1;
		int flag=1;
		while(!list.isEmpty()) {
			char a=list.get(0);
			key++;
			int b=list.lastIndexOf(a);
			if(0==b) {
				if(n%2==0) {
					out.println("Impossible");
					flag=0;
					break;
				}else {
					if(res>1) {
						out.println("Impossible");
						flag=0;
						break;
					}else {
						ans+=(n-1)/2-key;
						list.remove(0);
					}
				}
			}else {
				ans+=list.size()-1-b;
				list.remove(0);
				list.remove(b-1);
			}
			
		}
		if(flag==1) {
			out.print(ans);
		}
		out.flush();
		out.close();
	}
}

报时助手

问题描述
  给定当前的时间,请用英文的读法将它读出来。
  时间用时h和分m表示,在英文的读法中,读一个时间的方法是:
  如果m为0,则将时读出来,然后加上“o’clock”,如3:00读作“three o’clock”。
  如果m不为0,则将时读出来,然后将分读出来,如5:30读作“five thirty”。
  时和分的读法使用的是英文数字的读法,其中0~20读作:
  0:zero, 1: one, 2:two, 3:three, 4:four, 5:five, 6:six, 7:seven, 8:eight, 9:nine, 10:ten, 11:eleven, 12:twelve, 13:thirteen, 14:fourteen, 15:fifteen, 16:sixteen, 17:seventeen, 18:eighteen, 19:nineteen, 20:twenty。
  30读作thirty,40读作forty,50读作fifty。
  对于大于20小于60的数字,首先读整十的数,然后再加上个位数。如31首先读30再加1的读法,读作“thirty one”。
  按上面的规则21:54读作“twenty one fifty four”,9:07读作“nine seven”,0:15读作“zero fifteen”。
输入格式
  输入包含两个非负整数h和m,表示时间的时和分。非零的数字前没有前导0。h小于24,m小于60。
输出格式
  输出时间时刻的英文。
样例输入
0 15
样例输出
zero fifteen

import java.util.Scanner;
public class Main {
	static String[] ch= {"zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","twenty"};
	static String[] ch1= {"thirty","forty","fifty"};
	public static void main(String args[]) {
		Scanner sc=new Scanner(System.in);
		String ans="";
		int h=sc.nextInt();
		int m=sc.nextInt();
		
		if(h<=20) {
			ans+=ch[h]+" ";
		}else {
			ans+="twenty "+ch[h%10]+" ";
		}
		if(m==0) {
			ans+="o'clock";
		}else if(m<=20&&m>0) {
			ans+=ch[m];
		}else if(m>20&&m<30) {
			ans+="twenty "+ch[m%10];
		}else {
			int a=m/10;
			int b=m%10;
			ans+=ch1[a-3];
			if(b!=0) {
				ans+=" "+ch[b];
			}
		}
		System.out.println(ans);
		
	}

}

龟兔赛跑预测

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
  话说这个世界上有各种各样的兔子和乌龟,但是研究发现,所有的兔子和乌龟都有一个共同的特点——喜欢赛跑。于是世界上各个角落都不断在发生着乌龟和兔子的比赛,小华对此很感兴趣,于是决定研究不同兔子和乌龟的赛跑。他发现,兔子虽然跑比乌龟快,但它们有众所周知的毛病——骄傲且懒惰,于是在与乌龟的比赛中,一旦任一秒结束后兔子发现自己领先t米或以上,它们就会停下来休息s秒。对于不同的兔子,t,s的数值是不同的,但是所有的乌龟却是一致——它们不到终点决不停止。
  然而有些比赛相当漫长,全程观看会耗费大量时间,而小华发现只要在每场比赛开始后记录下兔子和乌龟的数据——兔子的速度v1(表示每秒兔子能跑v1米),乌龟的速度v2,以及兔子对应的t,s值,以及赛道的长度l——就能预测出比赛的结果。但是小华很懒,不想通过手工计算推测出比赛的结果,于是他找到了你——清华大学计算机系的高才生——请求帮助,请你写一个程序,对于输入的一场比赛的数据v1,v2,t,s,l,预测该场比赛的结果。
输入格式
  输入只有一行,包含用空格隔开的五个正整数v1,v2,t,s,l,其中(v1,v2<=100;t<=300;s<=10;l<=10000且为v1,v2的公倍数)
输出格式
  输出包含两行,第一行输出比赛结果——一个大写字母“T”或“R”或“D”,分别表示乌龟获胜,兔子获胜,或者两者同时到达终点。
  第二行输出一个正整数,表示获胜者(或者双方同时)到达终点所耗费的时间(秒数)。
样例输入
10 5 5 2 20
样例输出
D
4
样例输入
10 5 5 1 20
样例输出
R
3
样例输入
10 5 5 3 20
样例输出
T
4

import java.util.Scanner;


public class Main {
	static String[] ch= {"zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","twenty"};
	static String[] ch1= {"thirty","forty","fifty"};
	public static void main(String args[]) {
		Scanner sc=new Scanner(System.in);
		int v1=sc.nextInt();
		int v2=sc.nextInt();
		int t=sc.nextInt();
		int s=sc.nextInt();
		int l=sc.nextInt();
		
		int ans1=0;    //兔子;
		int res=0;     //兔子的时间
		int ans2=0;     //乌龟
		int d=0;
		if(v1==v2) {
			System.out.println("D");
			System.out.println(l/v1);
		}else if(v1<v2){
			System.out.println("T");
			System.out.println(l/v2);
		}else {
			while(true) {
				if(ans1==l&&ans2==l) {
					System.out.println("D");
					System.out.println(res);
					break;
				}
				if(ans1==l&&ans2<l) {
					System.out.println("R");
					System.out.println(res);
					break;
				}
				if(ans1<l&&ans2==l) {
					System.out.println("T");
					System.out.println(res);
					break;
				}
				
				ans2+=v2;
				res++;
				if(d==0) {
					ans1+=v1;
					if((ans1-ans2)>=t) {
						d=s;
					}
				}else {
					d--;
				}
				
			}
		}
		
		
	}

}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,带分数可以用分数类来表示。下面是一个简单的带分数类的实现: ```java public class Fraction { private int integer; private int numerator; private int denominator; public Fraction(int integer, int numerator, int denominator) { this.integer = integer; this.numerator = numerator; this.denominator = denominator; simplify(); } private void simplify() { if (numerator < 0 && denominator < 0) { numerator = -numerator; denominator = -denominator; } if (denominator < 0) { numerator = -numerator; denominator = -denominator; } if (integer < 0 && numerator > 0) { numerator = -numerator; } if (integer < 0 && numerator == 0) { integer = -integer; } if (numerator >= denominator) { integer += numerator / denominator; numerator = numerator % denominator; } int gcd = gcd(numerator, denominator); numerator /= gcd; denominator /= gcd; } private int gcd(int a, int b) { if (b == 0) { return a; } return gcd(b, a % b); } public Fraction add(Fraction other) { int newNumerator = this.numerator * other.denominator + other.numerator * this.denominator; int newDenominator = this.denominator * other.denominator; int newInteger = this.integer + other.integer; return new Fraction(newInteger, newNumerator, newDenominator); } public String toString() { if (integer == 0 && numerator == 0) { return "0"; } String result = ""; if (integer != 0) { result += integer; if (numerator != 0) { result += "_"; } } if (numerator != 0) { result += numerator + "/" + denominator; } return result; } } ``` 这个带分数类实现了以下功能: - 构造函数可以根据整数部分、分子和分母创建一个带分数对象。 - simplify() 方法可以将带分数对象化简,如将负号移到分子上、将整数部分和真分数部分合并、将分数化简等。 - add() 方法可以将两个带分数对象相加,返回一个新的带分数对象。 - toString() 方法可以将带分数对象转换为字符串形式。 这个类实现了带分数的加法操作,可以参考这个类来实现其他的运算操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值