第五次笔试,最后半个小时愣是没把第一题的剩下0.2和最后一题的剩下0.545推进一点点。最后一题致命打击,完全不知道怎么去优化。
0.8 1.0 0.455
1.(0.8)对输入字符串数组进行处理,字符串长度大于8就截成两个字符串,长度小于8就用0填补至长度等于8,对字符串数据进行从小到大排序,输出。
笔试想法:对输入的字符串进行判断长度,如果大于8就就进行截断,小于或者等于8的时候就直接加入数组,最后输出的时候再对字符串进行判断,如果等于8直接输出,小于8就填补0至长度为8。
现在想法(刚笔试完):写思路的时候突然想起来为什么通过80%,因为忘了考虑字符串长度大于16的情况,zz。
(只有在考完的时候才头脑清醒)
代码:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
String line = in.nextLine().trim();
String[] ss = line.split(" ");;
ArrayList<String> result = new ArrayList<>();
for (String s : ss) {
if((s = s.trim()).equals("")) continue;
if(s.length() == 8) {
result.add(s);
}else if(s.length()>8) {
while(s.length() > 8) {
result.add(s.substring(0, 8));
s = s.substring(8);
}
result.add(s);
}else {
result.add(s);
}
}
result.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
for(int i=0;i<Math.min(o1.length(), o2.length());i++) {
if(o1.charAt(i)>o2.charAt(i)) {
return 1;
}
if(o1.charAt(i)<o2.charAt(i)) {
return -1;
}
}
return 0;
}
});
for (String string : result) {
if(string.length() != 8) {
int size = 8-string.length();
for(int i=0;i<size;i++) {
string += "0";
}
}
System.out.print(string+" ");
}
}
}
2.(1.0)对字符串进行展开即每个括号前有一个数字k,将括号里的字符串复制k遍,最后倒序输出。
例如abc3(A),输出AAAcba
笔试想法:利用栈来完成,判断当前遍历字符是否为右括号 )、]、}其中的一个,不是则直接入栈,否则退栈,直至找到与之匹配的左括号,到左括号之前的字符串s都是要复制的,再退一个栈就是复制次数k,将s复制k次入栈,注意入栈顺序,因为最后需要倒序输出。
代码:
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine().trim();
if(s == null || s.length() == 0) return;
char[] chars = s.toCharArray();
Stack<Character> stack = new Stack<>();
for (int i=0;i<chars.length;i++) {
if(chars[i] == ')'){
String temp = "";
char c = stack.pop();
while(c != '(') {
temp = temp + c;
c = stack.pop();
}
int times = Integer.valueOf(String.valueOf(stack.pop()));
if(temp.length() > 0) {
for(int j=0;j<times;j++) {
char[] cs = temp.toCharArray();
for(int k=cs.length-1;k>=0;k--) {
stack.push(cs[k]);
}
}
}
}else if(chars[i] == ']') {
String temp = "";
char c = stack.pop();
while(c != '[') {
temp = temp + c;
c = stack.pop();
}
int times = Integer.valueOf(String.valueOf(stack.pop()));
if(temp.length() > 0) {
for(int j=0;j<times;j++) {
char[] cs = temp.toCharArray();
for(int k=cs.length-1;k>=0;k--) {
stack.push(cs[k]);
}
}
}
}else if(chars[i] == '}') {
String temp = "";
char c = stack.pop();
while(c != '{') {
temp = temp + c;
c = stack.pop();
}
int times = Integer.valueOf(String.valueOf(stack.pop()));
if(temp.length() > 0) {
for(int j=0;j<times;j++) {
char[] cs = temp.toCharArray();
for(int k=cs.length-1;k>=0;k--) {
stack.push(cs[k]);
}
}
}
}else {
stack.push(chars[i]);
}
}
while(!stack.isEmpty()) {
char c = stack.pop();
System.out.print(c);
}
}
}
3.(0.445)有一个n*m的地图,每个坐标有一个高度值,你可以往坐标上下左右走,但保证下一个坐标未走过且高度大于现在的坐标,求A到B有多少条路径,模1000000000。
笔试想法:就是递归+剪枝,从上下左右四个坐标且符合①未走过②高度大于当前坐标这两个条件的坐标走。
(复杂度太高,只通过45.5%,我完全不知道怎么改,我就是个菜鸡)
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int[][] h = new int[n][m];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
h[i][j] = in.nextInt();
int ai = in.nextInt();
int aj = in.nextInt();
int bi = in.nextInt();
int bj = in.nextInt();
boolean[][] r = new boolean[n][m];//为true表示此坐标走过
int sum = forward(r, ai, aj, bi, bj, h, 0);
System.out.println(sum);
}
public static int forward(boolean[][] r,int crri,int crrj,int bi,int bj,int[][] h,int sum){
if(crri==bi && crrj==bj) {
sum++;
return sum%1000000000;
}
//将当前坐标置为走过
r[crri][crrj] = true;
//向上走
if(crri-1>=0 && h[crri-1][crrj] > h[crri][crrj] && r[crri-1][crrj] == false) {
sum = forward(r, crri-1, crrj, bi, bj, h, sum);
}
//向下走
if(crri+1<h.length && h[crri+1][crrj] > h[crri][crrj] && r[crri+1][crrj] == false) {
sum = forward(r, crri+1, crrj, bi, bj, h, sum);
}
//向左走
if(crrj-1>=0 && h[crri][crrj-1] > h[crri][crrj] && r[crri][crrj-1] == false) {
sum = forward(r, crri, crrj-1, bi, bj, h, sum);
}
//向右走
if(crrj+1<h[0].length && h[crri][crrj+1] > h[crri][crrj] && r[crri][crrj+1] == false) {
sum = forward(r, crri, crrj+1, bi, bj, h, sum);
}
//将当前坐标置为未走过
r[crri][crrj] = false;
return sum;
}
}
2019/04/10 21:56 记录一下笔试的想法,后续将通过社区更新所有AC代码