【蓝桥日记⑥】2013第四届省赛(软件类)JavaA组@答案解析
文章目录
1、世界末的星期
解法:日期函数Calendar
package fourSession;
import java.util.Calendar;
/*** 2013第四届省赛 1、世纪末的星期 ***/
public class test1 {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
int year = 1999;
for (year = 1999; year < 1000000; year += 100) {
calendar.set(year, 11, 31);
if (calendar.get(Calendar.DAY_OF_WEEK) == 1) break;
}
System.out.println(year);
}
}
答案:
2299
2、振兴中华
解法:dfs
package fourSession;
/*** 2013第四届省赛 2、振兴中华 ***/
public class test2 {
// 从 我 做 起 振 兴 中 华
// 1 2 3 4 5 6 7 8
static int[][] g = {
{
1, 2, 3, 4, 5}, {
2, 3, 4, 5, 6}, {
3, 4, 5, 6, 7}, {
4, 5, 6, 7, 8}};
static int ans = 0;
public static void main(String[] args) {
dfs(0, 0, 1);
System.out.println(ans);
}
private static void dfs(int x, int y, int pre) {
if (x == 3 && y == 4) {
ans++;
return;
}
if (x + 1 < 4 && g[x + 1][y] == pre + 1) dfs(x + 1, y, pre + 1);
if (y + 1 < 5 && g[x][y + 1] == pre + 1) dfs(x, y + 1, pre + 1);
}
}
答案:
35
3、梅森素数
解法:BigInteger
package fourSession;
import java.math.BigInteger;
/*** 2013第四届省赛 3、梅森素数 ***/
public class test3 {
public static void main(String[] args) {
BigInteger x = BigInteger.TWO;
x = x.pow(11213);
x = x.subtract(BigInteger.ONE);
String sx = x.toString();
String ans = sx.substring(sx.length() - 100, sx.length());
System.out.println(ans);
}
}
答案:
8586718527586602439602335283513944980064327030278104224144971883680541689784796267391476087696392191
4、颠倒的价牌
解法:暴力枚举
package fourSession;
import java.io.CharArrayReader;
import java.util.ArrayList;
/*** 2013第四届省赛 4、颠倒的价牌 ***/
public class test4 {
static class Price{
int p; //原价
int rp; //颠倒价
Price(int p, int rp) {
this.p = p;
this.rp = rp;
}
}
static ArrayList<Price> a1 = new ArrayList<>();
static ArrayList<Price> a2 = new ArrayList<>();
public static void main(String[] args) {
// 枚举四位数,简单筛选,将赔200多的和赚800多的分别加入集合
// 遍历集合的两两组合,求差为558的组合
for (int i = 1000; i <= 9999; i++) {
int ri = reverseI(i);
if (i - ri > -300 && i - ri < -200) a1.add(new Price(i, ri));
if (i - ri > 800 && i - ri < 900) a2.add(new Price(i, ri));
}
boolean find = false;
for (Price a : a1) {
for (Price b : a2) {
if (a.p - a.rp + b.p - b.rp ==558) {
System.out.println(a.rp);
find = true;
break;
}
}
if (find) break;
}
}
private static int reverseI(int x) {
char[] cs = (x + "").toCharArray();
if (cs[0] == '0' || cs[3] == '0') return 1;
int ans = 0, t = 1;
for (int i = 0; i < 4; i++) {
if (cs[i] == '3' || cs[i] == '4' || cs[i] == '7') return 1;
if (cs[i] == '2') {
cs[i] = '5';
} else if (cs[i] == '5') {
cs[i] = '2';
} else if (cs[i] == '6') {
cs[i] = '9';
} else if (cs[i] == '9') {
cs[i] = '6';
}
ans += t * (cs[i] - '0');
t *= 10;
}
return ans;
}
}
答案:
9088
5、三部排序
解法:三向切分排序
有兴趣的可以看看我之前的总结:排序算法总结☑▁▂▃▅▂▃▁▂▃▇▆▃▂▁
package fourSession;
/*** 2013第四届省赛 5、三部排序 ***/
public class test5 {
static void sort(int[] x) {
int p = 0;
int left = 0;
int right = x.length - 1;
while (p <= right) {
if (x[p] < 0) {
int t = x[left];
x[left] = x[p];
x[p] = t;
left++;
p++;
} else if (x[p] > 0) {
int t = x[right];
x[right] = x[p];
x[p] = t;
right--;
//p++;
} else {
p++;
}
}
show(x);
}
static void show(int[] x) {
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + ",");
}
System.out.println();
}
public static void main(String[] args) {
//int[] x = {25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0};
sort(new int[]{
-1, 0, 1, -2, 0, 2, -3, 0, 0, 3, -4, -5, 4, -6, 0, 5, 6});
sort(new int[]{
-1, 0, -1, -2, 0, -2, -3, 0, 0, -3, -4, -5, -4, -6, 0, -5, -6});
sort(new int[]{
1, 0, 1, 2, 0, 2, 3, 0, 0, 3, 4, 5, 4, 6, 0, 5, 6});
}
}
答案:
p++
6、逆波兰表达式
package fourSession;
/*** 2013第四届省赛 6、逆波兰表达式 ***/
public class test6 {
static int[] evaluate(String x) {
if (x.length() == 0) return new int[]{
0, 0};
char c = x.charAt(0);
if (c >= '0' && c <= '9') return new int[]{
c - '0', 1};
int[] v1 = evaluate(x.substring(1));
int[] v2 = evaluate(x.substring(1 + v1[1]));
int v = Integer.MAX_VALUE;
if (c == '+') v = v1[0] + v2[0];
if (c == '*') v = v1[0] * v2[0];
if (c == '-') v = v1[0] - v2[0];
return new int[]{
v, 1 + v1[1] + v2[1]};
}
public static void main(String[] args) {
System.out.println(evaluate("-+3*5+261")[0]);
System.out.println(evaluate("+*35*42")[0]);
}
}
答案:
evaluate(x.substring(1 + v1[1]))
7、错误票据
解法一:List排序
package fourSession;
import java.util.*;
/*** 2013第四届省赛 7、错误票据 ***/
public class test7 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
ArrayList<Integer> list = new ArrayList();
sc.nextLine();
for (int i = 0; i < n; i++) {
String s = sc.nextLine();
String[] ss = s.split(" ");
for (int j = 0; j < ss.length; j++) {
list.add(Integer.parseInt(ss[j]));
}
}
sc.close();
int less = 0, same = 0;
Collections.sort(list);
for (int i = 1; i < list.size(); i++) {
if (list.get(i).equals(list.get(i - 1))) same = list.get(i);
if (list.get(i - 1) + 2 == list.get(i)) less = list.get(i) - 1;
}
System.out.println(less + " " + same);
}
}
解法二:Set集合去重
package fourSession;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.TreeSet;
/*** 2013第四届省赛 7、错误票据 ***/
public class test7 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
ArrayList<Integer> list = new ArrayList();
sc.nextLine();
for (int i = 0; i < n; i++) {
String s = sc.nextLine();
String[] ss = s.split(" ");
for (int j = 0; j < ss.length; j++) {
list.add(Integer.parseInt(ss[j]));
}
}
sc.close();
int pre = -1, less = 0, same = 0;
TreeSet<Integer> set = new TreeSet();
for (Integer v : list) {
if (set.contains(v)) {
same = v;
}
set.add(v);
}
for (Integer key : set) {
if (pre == -1 || pre + 1 == key) {
pre = key;
} else {
less = key - 1;
break;
}
}
System.out.println(less + " " + same);
}
}
8、带分数
解法:全排列
package fourSession;
import java.util.Scanner;
/*** 2013第四届省赛 8、带分数 ***/
public class test8 {
static int N;
static int ans = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
sc.close();
int[] arr = {
1, 2, 3, 4, 5, 6, 7, 8, 9};
backtrack(arr, 0, arr.length);
System.out.println(ans);
}
private static void backtrack(int[] arr, int begin, int end) {
if (begin == end) {
if (check(arr)) ans++;
return;
}
for (int i = begin; i < end; i++) {
int t = arr[begin]; arr[begin] = arr[i]; arr[i] = t;
backtrack(arr, begin + 1, end);
t = arr[begin]; arr[begin] = arr[i]; arr[i] = t;
}
}
private static boolean check(int[] arr) {
int num1, num2, num3;
for (int i = 1; i <= 7; i++) {
num1 = toInt(arr, 0, i);
if (num1 > N) return false;
for (int j = 1; j <= 8 - i; j++) {
num2 = toInt(arr, i, j);
num3 = toInt(arr, i + j, 9 - i - j);
if (num2 % num3 == 0) {
if (num1 + num2 / num3 == N) return true;
}
}
}
return false;
}
private static int toInt(int[] arr, int pos, int len) {
int t = 1, x = 0;
for (int i = pos + len - 1; i >= pos; i--) {
x += arr[i] * t;
t *= 10;
}
return x;
}
}
9、剪格子
解法:DFS
package fourSession;
import java.util.Scanner;
/*** 2013第四届省赛 9、剪格子 ***/
public class test9 {
static int m, n;
static int[][] g;
static int avg;
static int ans;
static int[] dirs = {
-1, 0, 1, 0, -1};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
g = new int[m][n];
int sum = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
g[i][j] = sc.nextInt();
sum += g[i][j];
}
}
sc.close();
boolean[][] mark = new boolean[m][n];
if (sum % 2 != 0) {
System.out.println(0);
} else {
avg = sum / 2;
ans = m * n;
mark[0][0] = true;
dfs(mark, 0, 0, sum - g[0][0], 1);
ans = (ans == m * n ? 0 : ans);
System.out.println(ans);
}
}
private static void dfs(boolean[][] mark, int x, int y, int sum, int cnt) {
if (sum < avg) return;
if (sum == avg) {
ans = Math.min(ans, cnt);
return;
}
for (int i = 0; i < 4; i++) {
int newX = x + dirs[i], newY = y + dirs[i + 1];
if (newX >= 0 && newX < m && newY >= 0 && newY < n && !mark[newX][newY]) {
mark[newX][newY] = true;
dfs(mark, newX, newY, sum - g[newX][newY], cnt + 1);
mark[newX][newY] = false;
}
}
}
}
10、大臣的旅费
解法:树的直径/树形DP
package fourSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
/*** 2013第四届省赛 10、大臣的旅费 ***/
public class test10 {
static int n;
static HashMap<Integer, ArrayList<int[]>> g;
static int ans = -1;
static int leaf = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
g = new HashMap();
for (int i = 1; i < n; i++) {
int from = sc.nextInt();
int to = sc.nextInt();
int weight = sc.nextInt();
if (!g.containsKey(from)) g.put(from, new ArrayList<int[]>());
if (!g.containsKey(to)) g.put(to, new ArrayList<int[]>());
g.get(from).add(new int[]{
to, weight});
g.get(to).add(new int[]{
from, weight});
}
dfs(1, 1, 0);
dfs(leaf, leaf, 0);
System.out.println(dis2money(ans));
}
private static void dfs(int v, int pre, int dis) {
boolean isLeaf = true;
for (int[] p : g.get(v)) {
if (p[0] == pre) continue;
isLeaf = false;
dfs(p[0], v, dis + p[1]);
}
if (isLeaf && dis > ans) {
ans = dis;
leaf = v;
}
}
private static int dis2money(int dis) {
return 11 * dis + dis * (dis - 1) / 2;
}
}