大家有什么疑问可以在评论区评论,一起交流进步啊o(∩_∩)o
字符串循环左移
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String string = scanner.nextLine();
int length = string.length();
int frequency = length;
int n = scanner.nextInt() % length;
char[] chars = string.toCharArray();
for (int i = n; frequency-- > 0; i = ++i % length) {
System.out.print(chars[i]);
}
}
}
字符串左移相当于指针右移,移动了多少次可以直接从下标开始输出所有的字符就行了。
说反话-加强版
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String sentence = scanner.nextLine().trim();
String[] words = sentence.split("\\s+");
StringBuilder builder = new StringBuilder();
for (int i = words.length - 1; i >= 0; i--) {
builder.append(words[i]).append(" ");
}
System.out.print(builder.toString().trim());
}
}
这个简单的最后一个测试过不了,超时!!
port java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String sentence = scanner.nextLine();
char[] chars = sentence.toCharArray();
//这里可以变成链表
ArrayList<String> list = new ArrayList<>();
ArrayList<Character> word = new ArrayList<>();
for (int i = 0; i < chars.length; i++) {
if (' ' == chars[i]) {
continue;
}
word.add(chars[i]);
if (i + 1 > chars.length) {
break;
}
if (i + 1 == chars.length) {
String w = Main.charList2String(word);
list.add(w);
break;
}
if (chars[i + 1] == ' ') {
String w = Main.charList2String(word);
list.add(w);
word.clear();
}
}
StringBuilder result = new StringBuilder();
for (int i = list.size() - 1; i >= 0; i--) {
result.append(list.get(i)).append(" ");
}
System.out.print(result.toString().trim());
}
private static String charList2String(ArrayList<Character> chars) {
StringBuilder builder = new StringBuilder();
for (Character a : chars) {
builder.append(a);
}
return builder.toString();
}
}
MD这个也超时……我觉得我这个算法可以了,复杂度O(n),不知道为什么过不了?
有理数加法
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] nums = scanner.nextLine().split(" ");
String[] a = nums[0].split("/");
String[] b = nums[1].split("/");
int molecule = Integer.valueOf(a[0]) * Integer.valueOf(b[1]) + Integer.valueOf(b[0]) * Integer.valueOf(a[1]);
int denominator = Integer.valueOf(a[1]) * Integer.valueOf(b[1]);
int min = molecule > denominator ? denominator : molecule;
for (int i = 2; i <= min; i++) {
if (molecule % i == 0 && denominator % i == 0) {
molecule /= i;
denominator /= i;
min = molecule > denominator ? denominator : molecule;
i = 1;
}
}
System.out.print(molecule);
if (denominator != 1) {
System.out.print("/" + denominator);
}
}
}
里面用到了求最大公约数的算法,总体上比较简单
通讯录的录入与显示
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArrayList<String> people = new ArrayList<>();
int N = scanner.nextInt();
for (int i = 0; i <= N; i++) {
String s = scanner.nextLine();
people.add(s);
}
//这里不知道为什么循环读取数据会读取一个空字符串,我也不太想研究为什么,直接删除就好。
people.remove(0);
String[] index = scanner.nextLine().split(" ");
Integer selectNum = Integer.valueOf(index[0]);
for (int i = 1; i <= selectNum; i++) {
if (Integer.valueOf(index[i]) < 0 || Integer.valueOf(index[i]) >= N) {
System.out.println("Not Found");
} else {
String target = people.get(Integer.valueOf(index[i]));
String[] fields = target.split(" ");
System.out.println(fields[0] + " " + fields[3] + " " + fields[4] + " " + fields[2] + " " + fields[1]);
}
}
}
}
没注意到输出字段的顺序不一样,我一看一个都没过,当时就懵逼了
有理数均值
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.nextLine());
String[] nums = scanner.nextLine().split(" ");
long[][] tem = new long[n][2];
//取数
for (int i = 0; i < nums.length; i++) {
String[] split = nums[i].split("/");
tem[i][0] = Long.parseLong(split[0]);
tem[i][1] = Long.parseLong(split[1]);
}
//求和
for (int i = 1; i < n; i++) {
tem[0] = plus(tem[0], tem[i]);
}
//最终化简
long[] result = simplify(tem[0][0], tem[0][1] * n);
System.out.print(result[0]);
if (result[1] != 1) {
System.out.print("/" + result[1]);
}
}
private static long[] plus(long[] a, long[] b) {
long molecule = a[0] * b[1] + b[0] * a[1];
long denominator = a[1] * b[1];
return simplify(molecule, denominator);
}
private static long[] simplify(long molecule, long denominator) {
long min = molecule > denominator ? denominator : molecule;
for (long i = 2; i <= min; i++) {
if (molecule % i == 0 && denominator % i == 0) {
molecule /= i;
denominator /= i;
min = molecule > denominator ? denominator : molecule;
i = 1;
}
}
return new long[]{molecule, denominator};
}
}
这个过不了测试点3,最大N错误,我不懂哪里有问题……
复数四则运算
import java.math.BigDecimal;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double a = scanner.nextDouble();
double b = scanner.nextDouble();
double c = scanner.nextDouble();
double d = scanner.nextDouble();
//加
double m = a + c;
double n = b + d;
output(a, b, c, d, m, n, "+");
//减
m = a - c;
n = b - d;
output(a, b, c, d, m, n, "-");
//乘
m = a * c - b * d;
n = b * c + a * d;
output(a, b, c, d, m, n, "*");
//除
m = (a * c + b * d) / (c * c + d * d);
n = (b * c - a * d) / (c * c + d * d);
output(a, b, c, d, m, n, "/");
}
private static void output(double a, double b, double c, double d, double m, double n, String op) {
//这里可以自己封装一个四舍五入的方法
BigDecimal t1 = new BigDecimal(m);
m = t1.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
BigDecimal t2 = new BigDecimal(n);
n = t2.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
System.out.printf("(%.1f%+.1fi) %s (%.1f%+.1fi) = ", a, b, op, c, d);
if (m == 0 && n == 0) {
System.out.println("0.0");
} else if (m != 0 && n == 0) {
System.out.printf("%.1f\n", m);
} else if (m == 0 && n != 0) {
System.out.printf("%.1fi\n", n);
} else {
System.out.printf("%.1f%+.1fi\n", m, n);
}
}
}
整数分解为若干项之和
import java.util.Scanner;
public class Main {
private static int sum = 0;
private static int count = 0;
private static int n = 0;
private static int[] num = new int[30];
private static int top = -1;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
dfs(1);
}
private static void dfs(int j) {
if (sum < n) {
for (int i = j; i <= n; i++) {
//下面这几句意思是:把当前坑位的值用dfs检测一下。
num[++top] = i;//把i放在当前坑位里面
sum += i;//把当前坑位的值加到sum里面,等价于sum=num[top]
dfs(i);//看看sum对不对
sum -= i;//把sum的值恢复原状
top--;//这里的--配合下次循环刚开始的++,两个操作合起来表示top的值没有便,现在考虑的还是这个坑位
}
} else if (sum == n) {
count++;
System.out.printf("%d=", n);
int k;
for (k = 0; k < top; k++) {
System.out.printf("%d+", num[k]);
}
if (count % 4 == 0 || num[top] == n) {
System.out.printf("%d\n", num[top]);
} else {
System.out.printf("%d;", num[top]);
}
}
}
}
这个难到我了,网上都说是深度优先算法,我一开始理解不来这个怎么和DFS联系起来。强行理解了一下感觉效果一点都不好,也是一边抄别人的代码一边思考,慢慢有了思路。
这个题就和解二元一次方程似的,从1开始一个一个数字试。输入n,那就有n个坑位,每个坑位都从1开始往上加。
先不在dfs方法里面传参数,j固定等于1,如果n等于7,那么代码的意思就是,前6个坑位都是1,第七个坑位从1到n挨个试了一遍,试了一遍指的是第七个坑位里面的每一个值都调用了一次dfs方法,实际上只有第七个坑位里面是1的时候,dfs里面会判断相等,第七个坑位是2、3、4、5、6、7的时候,sum的值都大于n所以没有再到下一个坑位。
第七个坑位全部试过之后,就回到了第六个坑位,第一次到第六个坑位的时候,把第六个坑位的值设置成了1,然后调用了dfs方法,因为sum是6小于7,所以进到了第七个坑位,现在从第七个坑位回来的时候,第六个坑位就该变成2了。这时候前5个坑位是1,第六个坑位是2,sum是7,所以第六个坑位是2的时候调用dfs,会判断输出,输出之后又回到第六个坑位,第六个坑位变成3、4、5、6、7,第六个坑位的这些值都要让sum在dfs里面走一遭。以此类推。
如果不在dfs里面传参会有一个小问题,按照上述的方式想象一下就会发现,在前4个坑位都是1,第五个坑位是2,的时候第六个坑位要是从1开始测试的话,就会出现 1 1 1 1 2 1的情况,这种情况也是7的分解式子,但是和要求的输出不一样,要保证后面的坑位里面的数字要比前面的坑位的数字大才行。也就是第五个坑位里面数字是2的时候,要告诉第六个坑位:不要从1开始循环了,从2开始循环吧。也就是后面这个坑位要从几开始循环,是由前面的坑位循环到几决定的,也就是为什么要给dfs传值。
这道题如果明确的知道n是多少,可以写一个n重循环来解决。因为不知道n是多少,所以用了递归来做。
这个题我刚开始一点头绪都没有,对我来说难度比较大,我能理解dfs算法,但是我无法把这道题和dfs算法联系起来,当我慢慢搞懂这道题的时候,我才把握到它和dfs算法的相似之处。一个坑位就相当于一个节点,每个坑位有n个数要测试,就代表有n条分支,用某个数测试就表示进入某个分支。每个节点有n个分支,n个节点就有n的n次方个分支,分支很多,但是也有很多分支是可以通过内部逻辑判断而不去执行的。这道题有点寻路的感觉,找出符合条件的某几个节点。
数列求和-加强版
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int n = scanner.nextInt();
if (n == 0){
System.out.println(0);
return;
}
int[] num = new int[n];
ArrayList<Integer> list = new ArrayList<>();
int flag = 0;
for (int i = n; i > 0; i--) {
int r = i * a + flag;
list.add(r % 10);
flag = r / 10;
}
for (int i = list.size(); i > 0; i--) {
System.out.print(list.get(i - 1));
}
}
}
一开始毫无疑问的超时,看了网上的答案知道了要一位一位的加,倒是不难理解,但是过不了最后的测试,我测了一下360多毫秒,抄了一百多毫秒,十有八九是Java的锅