在小组的安排下,这个暑假我们统一学习三个星期的算法,在这里让我感觉最大的感受是,前面有人引你入门真的好,可以少走很多的冤枉路,可以快速增长自己的能力和水平,但后续就要求自己自主的学习,因为别人的路线毕竟是别人的,不可能完全的适合自己的,但入门系列是每一个程序员或爱好算法的同学的必经之路,入门系列就是基础阶段,只有将基础打好,后面才能走的更远更好。在完成入门系列专项训练之后,我将自己做的题和做题过程中遇到的问题及解题思路总结成笔记。
记得上数据结构的时候老师说过,数据结构好比是武林高手的内功,往往刚修炼的时候内功比较的弱,但当我们持之以恒的练习,我们终将练就一身内功成就宗师。加油!
计算机并不仅仅能够处理数学问题,还可以用来处理文字,比如写文章、处理代码、记录信息等等……如果需要将各种语句记录在计算机中,就要用到字符串或者字符数组。
我们已经在最开始的地方尝试输出过"I love Luogu" 的字符串,也介绍过单个字符和数字对应的 ASCII 编码。在这一章会介绍字符串的存储和处理的方法。同时也初步接触了 STL,这使得可以“站在前人的肩膀上”完成程序,简化编程的难度。
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();//输入一串字符串
char[] array = str.toCharArray();//将输入的字符串变成数组
//遍历字符串数组,最每一个元素进行判断
for (int i = 0; i < array.length; i++) {
if (array[i] >= 'a' && array[i] <='z'){
array[i] = (char)(array[i] -('a' - 'A'));//'a' - 'A':获得字母大写和小写之间的差值。ASCALL
}
}
for (int i = 0; i < array.length; i++) {//遍历输出数据
System.out.print(array[i]);
}
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String str = sc.next();//输入字符串
char[] array = str.toCharArray();//将字符串变成char类型的字符数组
for (int i = 0; i < array.length; i++) {//遍历整个字符数组
for (int j = 0; j < n; j++) {//让每一数自增n次
array[i]++;
if (array[i] > 'z'){//若自增后元素大于‘z’,则从‘a'开始
array[i] = 'a';
}
}
}
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
}
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();//使用键盘输入,包含了空格和换行等
int count = 0;
char[] array = new char[str.length()+1];
//将字符串中的每个字符单独的存在array数组中
for (int i = 0; i < str.length(); i++) {
array[i] = str.charAt(i);
}
//遍历数组,判断字符是否时英文字母带小写,数字0-9;
for (int i = 0; i < array.length; i++) {
if ((array[i] >= 'a' && array[i] <= 'z')
|| (array[i] >= 'A' && array[i] <= 'Z')
|| (array[i] >= 48 && array[i] <= 57)
) {
count++;//符合的累加
}
}
System.out.println(count);
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = Integer.parseInt(sc.nextLine());
text = sc.nextLine();
String[] result = new String[n];
for (int i = 0; i < n; i++) {
result[i] = getResult(sc.nextLine());
}
for (String s : result) {
System.out.println(s);
}
}
//定义一个初始的字符串 全局的;
private static String text = "";
//条件一:后接插入,在文档后面插入字符串 str,并输出文档的字符串。
private static void append(String append_doc) {
text = text + append_doc;
}
//条件二:截取文档部分
private static void cut(int from, int range) {
text = text.substring(from, from+range);
}
//条件三:插入片段
private static void insert(int from, String insert_doc) {
String head = text.substring(0, from);
String rear = text.substring(from);
text = head + insert_doc + rear;
}
//条件四:查找子串
private static int search(String search_key) {
return text.indexOf(search_key);
}
//条件判断:
private static String getResult(String command) {
String[] arr = command.split(" ");//以空格为界限分割;
if (command.startsWith("1")) {//startsWith :判断字符串以什么开头。
append(arr[1]);
return text;
} else if (command.startsWith("2")) {
cut(Integer.parseInt(arr[1]), Integer.parseInt(arr[2]));
return text;
} else if (command.startsWith("3")) {
insert(Integer.parseInt(arr[1]), arr[2]);
return text;
} else {
return Integer.toString(search(arr[1]));
}
}
}
本题重点:
AC代码:(非常暴力的解法)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String a = sc.nextLine();
char[] str = a.toCharArray();//将字符串转换成数组,本题使用了nextLine:所以包括空格,空格也要按一下。
int count = 0;
for (int i = 0; i < str.length; i++) {
if (str[i] == ' ') {
count ++;
}
if (str[i] == 'a') {
count ++;
}
if (str[i] == 'b') {
count += 2;
}
if (str[i] == 'c') {
count += 3;
}
if (str[i] == 'd') {
count ++;
}
if (str[i] == 'e') {
count += 2;
}
if (str[i] == 'f') {
count += 3;
}
if (str[i] == 'g') {
count ++;
}
if (str[i] == 'h') {
count += 2;
}
if (str[i] == 'i') {
count += 3;
}
if (str[i] == 'j') {
count ++;
}
if (str[i] == 'k') {
count += 2;
}
if (str[i] == 'l') {
count += 3;
}
if (str[i] == 'm') {
count ++;
}
if (str[i] == 'n') {
count += 2;
}
if (str[i] == 'o') {
count += 3;
}
if (str[i] == 'p') {
count ++;
}
if (str[i] == 'q') {
count += 2;
}
if (str[i] == 'r') {
count += 3;
}
if (str[i] == 's') {
count += 4;
}
if (str[i] == 't') {
count ++;
}
if (str[i] == 'u') {
count += 2;
}
if (str[i] == 'v') {
count += 3;
}
if (str[i] == 'w') {
count ++;
}
if (str[i] == 'x') {
count += 2;
}
if (str[i] == 'y') {
count += 3;
}
if (str[i] == 'z') {
count += 4;
}
}
System.out.print(count + " ");
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int sum = 0;
String str = sc.next();//输入字符串
while(str.contains("VK")){//使用contains方法看字符串中是否包含VK,若有累加,并且将其置换成其他的数据
//replaceFirst() 方法使用给定的参数 replacement 替换字符串第一个匹配给定的正则表达式的子字符串。
//循环操作,将所有的vk都进行计数和置换,
str = str.replaceFirst("VK","CC");
sum++;
}
//前面循环之后,剩下的v和k是组成不了vk的,担忧vv和kk,只能改变一个,若有置换一个就行了。
if (str.contains("VV") || str.contains("KK")){
sum++;
}
System.out.println(sum);
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int boy = 0,girl = 0;//分别累加boy和girl出现的次数
char[] a = new char[300];
for (int i = 0; i < str.length(); i++) {
a[i] = str.charAt(i);//获得字符串中的每一个字符并赋值给数组
}
for (int i = 0; i <= str.length(); i++) {//遍历字符串中的每一个字符
if (a[i]=='b'||a[i+1]=='o'||a[i+2]=='y')//判断连着的三个字母是否为b、o、y
boy++;//boy计数器加一
if (a[i]=='g'||a[i+1]=='i'||a[i+2]=='r'||a[i+3]=='l')//判断连着的三个字母是否为g、i、r、l
girl++;//girl计数器加一
}
System.out.println(boy+"\n"+girl);
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1 = sc.next();
String str2 = sc.next();
char[] a = str1.toCharArray();
char[] b = str2.toCharArray();
int sum1 =1, sum2 = 1;//sum1 :彗星的累乘变量 sum2:队伍的累乘变量
for (int i = 0; i < str1.length(); i++) {//累乘彗星数值
sum1 *= (a[i] - 64);//char类型转int型
}
for (int i = 0; i < str2.length(); i++) {//同上
sum2 *= (b[i] - 64);
}
int n = sum1 % 47,m = sum2 % 47;//各自得到余数比较
if(n == m){
System.out.println("GO");
}else{
System.out.println("STAY");
}
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int a = 0,b =0,c = 0;
char[] arr = str.toCharArray();
for (int i = 0; i < str.length(); i+= 5) {
//当被复制的字符为‘a’时及四种可能
if (arr[i] == 'a'){
if(arr[i+3]=='a')
a = a;
else if(arr[i+3]=='b')
a=b;
else if(arr[i+3]=='c'){
a=c;
} else{
a=arr[i+3]-'0';//char类型转int类型
}
}
//当被复制的字符为‘b’时及四种可能
if(arr[i]=='b') {
if(arr[i+3]=='b')
b = b;
else if(arr[i+3]=='a'){
b=a;
} else if(arr[i+3]=='c'){
b=c;
}
else {
b = arr[i + 3] - '0';
}
}
//当被复制的字符为‘c’时及四种可能
if(arr[i]=='c') {
if(arr[i+3]=='c')
c = c;
else if(arr[i+3]=='a'){
c=a;
} else if(arr[i+3]=='b'){
c=b;
} else{
c=arr[i+3]-'0';
}
}
}
System.out.println(a + " " + b + " " + c);
}
}
本题重点:
AC代码:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
String str = sc.nextLine();
int[] count = new int[26];//数组的范围是26;对应26为英文字母
for (char c: str.toCharArray()) {//遍历字符串,让每一个字符-‘a’,在数组中对应的位置自增。
count[c - 'a'] ++;
}
Arrays.sort(count);//通过数组的升序方法升序。
int maxn = 0;
for (int i = 0; i < 26; i++) {//遍历获得最大的那个差值
if (count[i] != 0){
maxn = count[25] - count[i];
break;
}
}
if (maxn == 0 || maxn == 1) {//特殊情况事先判断一下。
System.out.println("No Answer\n0");
return;
}
for (int i = 2; i < maxn; i++) {//判断差值是否是是质数
if (maxn % i == 0) {
System.out.println("No Answer\n0");
return;
}
}
System.out.println("Lucky Word");
System.out.println(maxn);
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = Integer.parseInt(sc.nextLine());//这个就是输入i值,只是想用其他的方法实现
String text = "";//中间变量text
for (int i = 0; i < n; i++) {//遍历每一条数据
String a = sc.nextLine(),count = "";//输入每一行的数据
String[] b= a.split(" ");//使用split(“ ”)将输入的字符串按照空格分成数组
int f , g;
if (a.startsWith("a")) {//使用startWith来判断当前行是否是a开头
text = "a";//若是,将text赋值为a
f = Integer.parseInt(b[1]);
g = Integer.parseInt(b[2]);
} else if (a.startsWith("b")) {//同上
text = "b";
f = Integer.parseInt(b[1]);
g = Integer.parseInt(b[2]);
} else if (a.startsWith("c")) {//同上
text = "c";
f = Integer.parseInt(b[1]);
g = Integer.parseInt(b[2]);
} else {//若都不是,不用赋值,会自动使用上一次的text
f = Integer.parseInt(b[0]);
g = Integer.parseInt(b[1]);
}
switch (text) {//判断是那种可能,让后输出对应的输出格式
case "a":
count = f + "+" + g + "=" + (f+g);
break;
case "b":
count = f + "-" + g + "=" + (f-g);
break;
case "c" :
count = f + "*" + g +"=" + (f*g);
break;
}
System.out.println(count + "\n" + count.length());
}
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String a = sc.nextLine().toLowerCase();//不区分大小写,所以使用toLowerCase()方法输入的单词变成小写
String b = sc.nextLine().toLowerCase();//将文章语句全部变成小写
String[] c= b.split(" ");
int count = 0,index = 0;//
boolean flag = true;
for (int i = 0; i < c.length; i++) {
if (c[i].equals(a)){
count++;
flag = false;
}
if (flag){
index += c[i].length() + 1;
}
}
if (count > 0){
System.out.println(count +" "+ index);
}else{
System.out.println(-1);
}
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
String[] a = new String[2];
String symbol = "";
//判断输入的字符串是那种数
if(str.contains(".")){
symbol = ".";//小数
}else if(str.contains("/")){
symbol = "/";//分数
}else if(str.contains("%")){
symbol = "%";//百分数
}else{
symbol=null;//整数
}
//判断是什么数然后反转
if(symbol == null){//判断数据包含的符号,然后根据符号来计算不同的反转
character(str);
}else if(symbol.equals("%")){//根据 % 来分割字符串
character(str.substring(0,str.length()-1));
System.out.print("%");
}else if(symbol.equals("/")){
a = str.split("/");//根据 / 来分割字符串
character(a[0]);
System.out.print("/");
character(a[1]);
}else{
a = str.split("\\.");//根据.来分割字符串
character(a[0]);
System.out.print(".");
character(a[1]);
}
}
public static void character(String str){
int front = -1,back = -1;
//获得非零的首坐标
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)!='0'){
front=i;
break;
}
}
//获得非零的尾坐标
for(int i=str.length()-1;i>=0;i--){
if(str.charAt(i)!='0'){
back=i;
break;
}
}
//如果都是零的话直接输出零
if(front==-1){
System.out.print("0");
return;
}
//获得反转后的数字
for (int i = back; i >= front; i--) {
System.out.print(str.charAt(i));
}
}
}
本题重点:
AC代码:
/*
* 这道题自己琢磨了好久没有做出来,所以在网上找解解题方法,偶然间看到一篇题解,过程虽然简洁,但java方法的运用和思想挺好的
* 1.先将所有的英文数字和阿拉伯数字的平方求余对应,这时候用到了map的键值对
* 2.将输入的字符串通过trim()去掉首尾的空格,然后再使用split("\\s+")通过空格等为边界将字符串变成想要的单词数组。
* 3.在通过containsKey这个函数来检验输入的数据中是否有题中提到的那些单词,如果有就将对应的数据加到list链表中。
* 4.定义一个StringBuffer的字符串,这个字符串是可以通过append追加的。最后通过toString变成String类型
* */
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
String[] words = sc.nextLine().trim().split("\\s+");
//直接将对应的英文数字对应的数字平方根在求余。10和20求余后为零省略
Map map = new HashMap<>(25);
map.put("one", "01");
map.put("another", "01");
map.put("two", "04");
map.put("three", "09");
map.put("four", "16");
map.put("five", "25");
map.put("six", "36");
map.put("seven", "49");
map.put("eight", "64");
map.put("nine", "81");
map.put("eleven", "21");
map.put("twelve", "44");
map.put("thirteen", "69");
map.put("fourteen", "96");
map.put("fifteen", "25");
map.put("sixteen", "56");
map.put("seventeen", "89");
map.put("eighteen", "24");
map.put("nineteen", "61");
map.put("a", "01");
map.put("both", "04");
map.put("first", "01");
map.put("third", "09");
map.put("second", "04");
List list = new ArrayList<>();
for (String i: words) {
if (map.containsKey(i)) {
list.add(map.get(i));
}
}
if (list.isEmpty()) {
System.out.println(0);
}
//StringBuilder:可以追加字符的字符串,有线程保护,还有一个没有线程保护的时StringBuffer;
StringBuilder str = new StringBuilder();
//给链表中的数据进行自然的排序
list.sort(Comparator.naturalOrder());//将集合内部进行排序;
for (String i : list) {//遍历集合,将所有的字符累加在str上组成最小的数字
str.append(i);
}
String result = str.toString();
if (result.startsWith("0")) {//把这些两位数按数位排成一行,组成一个新数,如果开头为 0,就去 0。
result = result.substring(1);
}
System.out.println(result);
}
}
本题重点:
AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] n = new int[26];
String a;
char b;
//一共有4行数据
for(int i=0;i<=3;i++) {
a=sc.nextLine(); //输入一行字符串
for(int j=0;j<a.length();j++) {
b=a.charAt(j);
if(b>='A' && b<='Z') {
n[b-'A']++; //记录A-Z的字符的个数
}
}
}
//获得最大的数;
int o = getMax(n);
//输出”*“
for (int i = o; i > 0; i--) {//一共有max行.遍历每一行,判断是否有字符重复的次数达到当前行的大小
for (int j = 0; j < 26; j++) {//一共26个字母
if (n[j] == i){
System.out.print("* ");
n[j]--;
}else{
System.out.print(" ");
}
}
System.out.println();
}
System.out.print("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");//最下面对应的字符
}
public static int getMax(int []a){
int b = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] > b){
b = a[i];
}
}
return b;
}
}
本题重点: