public class 门牌制作 {
public static void main(String[] args) {
int ans = 0;
for (int i = 1; i <= 2020; i++) {
int num = i;
while (num != 0) {
int temp = num % 10;
if (temp == 2) {
ans++;
}
num /= 10;
}
}
System.out.println(ans);
}
}
答案:624
**
- 首先我没有读懂题
- 其次我想复杂了
- 因为我被大数据吓住了
- 最后我要是冷静下来分析,也不会哭成个死人
**
分析
首先知道这个矩阵有多少行和列,可以打开记事本来看,或者pycharm可以看有多少行和列
或者用代码
将txt文件的数据全部复制到控制台
Scanner read = new Scanner(System.in);
String string = "";
for (int i = 1;; i++) {//i从1 开始
string = read.nextLine();
if (string != null) {
System.out.print(i+" ");
}
}
完整代码
import java.util.Scanner;
public class 寻找2020 {
static int count = 0;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String[] str = new String[300];// 知道矩阵有多少行
for (int i = 0; i < str.length; i++) {
str[i] = input.nextLine();
}
char[][] cs = new char[str.length][str.length];
for (int i = 0; i < str.length; i++) {
cs[i] = str[i].toCharArray();
}
fun(cs);
System.out.println(count);
}
public static void fun(char[][] cs) {
int n = cs.length;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// 行
if (j + 3 < n) {
if (cs[i][j] == '2' && cs[i][j + 1] == '0' && cs[i][j + 2] == '2' && cs[i][j + 3] == '0') {
count++;
}
}
// 列
if (i + 3 < n) {
if (cs[i][j] == '2' && cs[i + 1][j] == '0' && cs[i + 2][j] == '2' && cs[i + 3][j] == '0') {
count++;
}
}
// 左上到右下
if (i + 3 < n && j + 3 < n) {
if (cs[i][j] == '2' && cs[i + 1][j + 1] == '0' && cs[i + 2][j + 2] == '2'
&& cs[i + 3][j + 3] == '0') {
count++;
}
}
}
}
}
}
该题总结:不要看到这么多数据就吓死了,不知道怎么分析!!该画图!!就画图!!画图!!想清楚下标的合法范围,然后统计行、列、左上到右下(看清楚,只有左上到右下,别多算右上到左下)
结果:
我写的烂大街的代码。。。。。
public static void main(String[] args) {
int n = 40;//通过调试,发现n要取大一点,第20行20列才可能被填充
int[][] arr = new int[n][n];
arr[0][0] = 1;
int i = 0, j = 1;
while (i < n && j < n) {
while (j != 0 && j < n - 1) {
if (i == 0) {
arr[i][j] = arr[i][j - 1] + 1;
} else {
arr[i][j] = arr[i - 1][j + 1] + 1;
}
i++;
j--;
}
if (i < n && j < n - 1 && i >= 1 && j >= 0) {
arr[i][j] = arr[i - 1][j + 1] + 1;
i++;
} else {
break;
}
while (i != 0 && i < n - 1) {
if (j == 0) {
arr[i][j] = arr[i - 1][j] + 1;
} else {
arr[i][j] = arr[i + 1][j - 1] + 1;
}
i--;
j++;
}
if (i < n - 1 && j < n && i >= 0 && j >= 1) {
arr[i][j] = arr[i + 1][j - 1] + 1;
j++;
} else {
break;
}
}
for (int[] temp : arr) {
System.out.println(Arrays.toString(temp));
}
}
当然这道题可以推出公式!没想到吧!
分析:我们是从1开始填充这个二维数组,我们要求的位置都是位于反对角线上的,所以所处的(x,y),x=y,可以写成(x,x)。我们要求第n行第n列的值,可以先求出左上部分已经填满的个数,再加上自身所在的行数,即为答案。
- 那我们怎么求出已经填满的个数呢?
我们可以先求出左上部分的个数,我们可以以“斜行”来命名从右上到左下,
要求第二行第二列的值,就要先填满1斜行、2斜行,即1+2=3,表示前面已经填满了3个数,那么再加上第二行的2,即3+2=5,为答案。
我们可以发现规律,要求某个对角线上的数,先求出已填满的斜行数,累加即为左上部分填满的元素的个数,通过递推得公式:
1+2+3…+2*(n-1),S和=(2n-1)(2n-2)/2,这就是左上部分的已填满的个数。
另外,该对角线所处的行决定了“从已填满的斜行的下一个斜行”,需要填满几个数即走到该位置
所以,
S总=(2n-1)(2n-2)/2+n
答案:761
我放弃
答案80
*补充一个字符数组转为String的方法
char[] cs = new char[26];
for (int i = 0; i < 26; i++) {
cs[i] = (char) ('a' + i);
}
**String str = new String(cs);**
System.out.println(str);
这道题纯推导
sum要转型!细节决定成败,不要马虎,越简单越要想清楚
public class 成绩分析 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int[] arr = new int[n];
for (int i = 0; i < arr.length; i++) {
arr[i] = input.nextInt();
}
int max = arr[0];
int min = arr[0];
double sum = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
} else if (arr[i] < min) {
min = arr[i];
}
sum += arr[i];
}
System.out.println(max);
System.out.println(min);
System.out.printf("%.2f", sum / n);
//或者 System.out.println(String.format("%.2f", (double) sum / n));
}
}
public class 单词分析 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String string = sc.nextLine();
char[] temp = string.toCharArray();
int[] count = new int[26];
for (int i = 0; i < temp.length; i++) {
count[temp[i] - 'a']++;
}
int max = Integer.MIN_VALUE;
int index = -1;
for (int i = 0; i < count.length; i++) {
if (count[i] > max) {
max = count[i];
index = i;
}
}
System.out.println((char) ('a' + index));
System.out.println(max);
}
}
方法一:动态规划
public class 数字三角形 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[][] arr = new int[n][n];
int[][] res = new int[n][n];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j <= i; j++) {
arr[i][j] = scanner.nextInt();
}
}
res[0][0] = arr[0][0];
for (int i = 1; i < arr.length; i++) {
for (int j = 0; j <= i; j++) {
if (j == 0) {
res[i][j] = res[i - 1][j] + arr[i][j];
} else if (i == j) {
res[i][j] = res[i - 1][j - 1] + arr[i][j];
} else {
res[i][j] = Math.max(res[i - 1][j - 1], res[i - 1][j]) + arr[i][j];
}
}
}
int ans = 0;
ans = n % 2 == 1 ? res[n - 1][n / 2] : Math.max(res[n - 1][n / 2 - 1], res[n - 1][n / 2]);
System.out.println(ans);
}
}
方法二:适合考试时做不出来的动态规划就用dfs
找到所有符合条件的路径之和,并与max作比较
public class 数字三角形2 {
static int max = -1;
static HashSet<Integer> dp = new HashSet<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[][] arr = new int[n][n];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j <= i; j++) {
arr[i][j] = scanner.nextInt();
}
}
dfs(arr, 0, 0, 0, 0, 0, new boolean[n][n]);// 找出所有符合的路径之和
// System.out.println(dp);// 查看是否符合案例
System.out.println(max);
}
public static void dfs(int[][] arr, int row, int col, int sum, int left, int right, boolean[][] flag) {
if (row == arr.length - 1 && Math.abs(right - left) <= 1) {
// dp.add(sum + arr[row][col]);
if (sum + arr[row][col] > max) {
max = sum + arr[row][col];
}
return;
}
if (row >= arr.length || col >= arr.length) {
return;
}
// 走
if (!flag[row][col]) {
flag[row][col] = true;
dfs(arr, row + 1, col, sum + arr[row][col], left + 1, right, flag);
dfs(arr, row + 1, col + 1, sum + arr[row][col], left, right + 1, flag);
flag[row][col] = false;
}
}
}
方法一:暴力
public class 子串分值和 {
static char[] cs;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String string = sc.nextLine();
int sum = 0;
cs = string.toCharArray();
for (int i = 0; i < cs.length; i++) {
for (int j = i + 1; j <= cs.length; j++) {
sum += func(i, j);
}
}
System.out.println(sum);
}
public static int func(int i, int j) {
HashSet<Character> set = new HashSet<>();
while (i < j) {
set.add(cs[i]);
i++;
}
return set.size();
}
}
这道题若使用subString(),消耗较大,采用传入下标,用set进行统计。
但是只能得一半的分。
方法二:官方解答
最后一题放弃