资源限制
时间限制: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
}
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--;
}
}
}
}
}