题解 - 暴力、枚举、模拟
01 - 单词分析
题目
给了一个单词,找到出现最多的字母和这个字母出现的次数。
样例
longlonglongistoolong
o
6
思路
数组下标具有实际意义:
下标代表字母,元素代表该字母出现的次数
常用ASCII码:A:65 —— a:97 —— 0:48
代码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//输入
String s = sc.next();
//定义一个数组,下标对应的26个字母,元素代表该字母出现次数
int[] z = new int[26];
//定义两个变量保存最大值及下标(字母)
int max = 0, k = 0;
//将单词的每一个字符取出来
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
//每取一个字母,数组对应下标+1
z[c-'a']++;
}
//找到最大值及其下标(字母)
for (int i = 0; i < z.length; i++) {
if (z[i] > max) {
max = z[i];
k = i;
}
}
//整形转化为字符并输出
System.out.println((char) (k + 97) + "\n" + z[k]);
sc.close();
}
02 - 四平方和
题目
对于一个给定的正整数,可能存在多种平方和的表示法。比如:
N = a2+b2+c2+d2
7 = 12+12+12+22
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法。
样例
12
0 2 2 2
思路
暴力!暴力!暴力破解
枚举所有情况,找到限制条件(N = a2+b2+c2+d2)
最后一定要优化(遍历次数之类的)
代码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i1 = 0; i1 * i1 <= n; i1++)
for (int i2 = i1; i2 * i2 <n; i2++)
for (int i3 = i2; i3 * i3 < n; i3++)
for (int i4 = i3; i4 * i4 < n; i4++) {
if (i1 * i1 + i2 * i2 + i3 * i3 + i4 * i4 == n) {
System.out.println(i1 + " " + i2 + " " + i3 + " " + i4);
return;
}
}
}
03 - 特别数的和
题目
在 1 到 n 中,所有数位中含有 2、0、1、9 的数字的和是多少?
在 1 到 40 中,这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。
样例
40
574
思路
将输入的数转为字符串,通过str.contains(“2”),来判断是否含有特别数来计数
代码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int sum = 0;
String s;
for (int i = 1; i <= n; i++) {
//整数转字符串
s = i + " ";
//判断是否包含特别数
if (s.contains("2") || s.contains("0") || s.contains("1") || s.contains("9"))
sum += i;
}
System.out.println(sum);
}
04 - 旋转
题目
我们用一个 n×m 的二维数组来表示一个图片,例如下面给出一个 3×4 的 图片的例子:
1 3 5 7
9 8 7 6
3 5 9 7
这个图片顺时针旋转 90 度后的图片如下:
3 9 1
5 8 3
9 7 5
7 6 7
给定初始图片,请计算旋转后的图片。
样例
3 4
1 3 5 7
9 8 7 6
3 5 9 7
3 9 1
5 8 3
9 7 5
7 6 7
思路
画图!
画图标注每个数字实际坐标后,很容易可以看出来关系式
根据关系式写程序
代码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] arr1 = new int[n][m];
for (int i = 0; i < arr1.length; i++)
for (int j = 0; j < arr1[i].length; j++)
arr1[i][j] = sc.nextInt();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print(arr1[n - j - 1][i] + " ");
}
System.out.println();
}
}
05 - 三连击
题目
将 1,2,…,9 共 9 个数分成 3 组,分别组成 3 个三位数,且使这 3 个三位数构成 1:2:3 的比例,试求出所有满足条件的 3 个三位数。
输出若干行,每行 3 个数字。按照每行第 1 个数字升序排列。
样例
192 384 576
…
…
思路
枚举所有情况,找到限制条件,剪枝
用数组表示1-9各数字出现次数,也可以用contains方法判断
代码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//枚举所有情况,由题找到限制条件(即三组数由1-9构成)
for (int i = 123; i < 330; i++) {
//判断第一个三位数是否每个位置不相等
if (i % 10 != i / 10 % 10 && i % 10 != i / 100 && i / 100 != i / 10 % 10 && i / 10 % 10 != 0
&& i % 10 != 0) {
//判断三组数是否由1-9构成
if(legal(i*1000000+i*2*1000+i*3)&&i!=0)
System.out.println(i+" "+i*2+" "+i*3);
}
}
sc.close();
}
//判断三组数是否由1-9构成
public static boolean legal(int n) {
int[] l = new int[10];
for (int i = 1; i < 10; i++) {
l[n % 10]++;
n /= 10;
}
for (int i = 1; i < 10; i++)
if (l[i] != 1)
return false;
return true;
}
06 - 质数
题目
我们知道第一个质数是 2、第二个质数是 3、第三个质数是 5……
请你计算第 2019 个质数是多少?
样例
无
思路
用一个变量保存每一个质数个数,数到2019输出
代码
public static void main(String[] args) {
int j = 0;
for (int i = 2; i < 100000; i++) {
if (isPrime(i)) {
j++;
}
//数到2019输出
if (j == 2019) {
System.out.println(i);
break;
}
}
}
//判断是否是质数
public static boolean isPrime(int n) {
for (int j = 2; j < n; j++) {
if (n % j == 0)
return false;
}
return true;
}
小结 一
- 数组的下标有时具有实际意义
- 常用ASCII码:A:65 —— a:97 —— 0:48
- 暴力破解题目时要注意优化代码(以免超时)
- str = i + " " (整型转字符串)
- 草稿纸上演算往往比手算或打字方便很多
- 枚举的方法:举出所有情况,找到限制条件,剪枝