1.【问题描述】
这题使用排列组合出每种数字顺序,然后对每组数字截出所有可能出现的3段 a1,a2,a3 ,只要满足a1 + a2 / a3 == N ,就满足条件
package 蓝桥杯校赛2018; import java.util.Scanner; public class A { static int[] t = new int[10]; static int[] a = new int[10]; static int num; static int count; public static void main(String[] args) { Scanner in = new Scanner(System.in); num = in.nextInt(); f(1); System.out.println(count); } //获取数组中一段拼接成数字 static double get(int c, int d) { int result = a[c]; for (int i = c + 1; i <= d; i++) { result = result * 10 + a[i]; } return result; } //判断是否满足 a1 + a2 / a3 == N static void is() { for (int i = 1; i < 8; i++) { for (int j = 1; j + i < 9; j++) { //System.out.println(1 + "," + i + " " + (i + 1) + "," + (i + j) + " " + (i + j + 1) + "," + 9); //System.out.println(get(1, i) + " " + get(i + 1, i + j) + " " + get(i + j + 1, 9)); if(get(1, i) + get(i + 1, i + j) / get(i + j + 1, 9) == num) { //System.out.println(get(1, i) + " " + get(i + 1, i + j) + " " + get(i + j + 1, 9)); count++; } } } } //这里dfs搜索出数字所有排列顺序 static void f(int n) { if (n == 10) { //System.out.println(Arrays.toString(a)); is(); return; } for (int i = 1; i < 10; i++) { if (t[i] == 0) { t[i] = 1; a[n] = i; f(n + 1); t[i] = 0; } } } }
2.【问题描述】
这题有点坑,10!= 3628800 ,如果直接排列组合出每种情况,那肯定会超时。就用案例 bdca ,题目有一个暗示,4!=24,那么我们可以把这24种情况分成4份,每份6个: 第0份 abcd 0 abdc 1 acbd 2 acdb 3 adbc 4 adcb 5 第1份 bacd 6 badc 7 bcad 8 bcda 9 bdac 10 bdca 11 第2份 cabd 12 cadb 13 cbad 14 cbda 15 cdab 16 cdba 17 第3份 ... b代表了第1份,去掉已经找过的b,剩下dca,3!=6,分成3份,每份2个, 0 acd 6 adc 7 1 cad 8 cda 9 2 dac 10 dca 11 确定了d在第2份,同样再找到ca,2!=2,分成2份,每份1个, 0 ac 10 1 ca 11 直接就可以确定c在第1份中,然后输出位置11
package 蓝桥杯校赛2018; import java.util.Arrays; import java.util.Scanner; public class B { static String s = "abcdefghij"; static int[] a = new int[11]; static int[] t = new int[11]; public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println(jc(10)); s = in.nextLine(); int slen = s.length(); int start = 0, end = slen; for (int i = 0; i < slen - 1; i++) { int len = 0; char[] ca = s.toCharArray(); char[] temp = Arrays.copyOf(ca, ca.length); Arrays.sort(temp); for (int j = 0, k = 0; j < ca.length; j++) { t[temp[j] - 'a'] = k++; } for (char c : ca) { a[len++] = t[c - 'a']; } end = jc(len); int size = end / len; end = start + (a[0] + 1) * size - 1; start += (a[0] * size); len--; s = new String(ca, 1, ca.length - 1); } System.out.println(start); } public static int jc(int n) { if (n == 1) { return 1; } return n * jc(n - 1); } }
先求出竖直高度y1,y2,根据y1,y2可以判断是否同序或者逆序, 如果n,m的是同序的话,求出他们水平位置x1,x2,然后相减即可 如果n,m是逆序的话,先计算出其中一层竖直对称位置m1,例如题目中:1对应6,2对应5,3对应4,然后再求出n,m1的水平位置,再相减
package 蓝桥杯校赛2018; import java.util.Scanner; public class C { public static void main(String[] args) { int k = 4, n = 7, m = 20; Scanner in = new Scanner(System.in); k = in.nextInt(); n = in.nextInt(); m = in.nextInt(); n--; m--; int y1 = n / k; int y2 = m / k; if (y1 > y2) { int t = y1; y1 = y2; y2 = t; } if ((y2 - y1) % 2 == 0) { // 在同序层上 int x1 = n % k; int x2 = m % k; if (x1 > x2) { int t = x1; x1 = x2; x2 = t; } System.out.println((y2 - y1) + (x2 - x1)); } else { // 在逆序层上 int sum = (m / k + 1) * k - 1 + (m / k) * k; int x1 = n % k; int x2 = (sum - m) % k; if (x1 > x2) { int t = x1; x1 = x2; x2 = t; } System.out.println((y2 - y1) + (x2 - x1)); } } }
描述
哥德巴赫猜想认为“每一个大于2的偶数,都能表示成两个质数之和”。
给定一个大于2的偶数N,你能找到两个质数P和Q满足P<=Q并且P+Q=N吗?
输入
一个偶数N(4 <= N <= 1000000)
输出
输出P和Q。如果有多组解,输出P最小的一组。
样例输入
10
样例输出
3 7
直接使用线性素数筛选,然后判判断即可
package 蓝桥杯校赛2018; import java.util.Scanner; public class D { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n; n = in.nextInt(); boolean[] prime = new boolean[n + 1]; for (int i = 2; i <= n; i++) { prime[i] = true; } for (int i = 2; i <= n; i++) { if (prime[i]) { for (int j = i + i; j <= n; j += i) { prime[j] = false; } } } for(int i = 0;i <= n;i++) { if(prime[i] && prime[n - i]) { System.out.println(i + " " + (n - i)); break; } } } }
描述
小Hi参加了一场大型马拉松运动会,他突然发现面前有一位参赛者背后的号码竟然和自己一样,也是666。仔细一看,原来那位参赛者把自己号码帖反(旋转180度)了,结果号码999看上去变成了号码666。
小Hi知道这次马拉松一共有N名参赛者,号码依次是1~N。你能找出所有可能因为贴反而产生歧义的号码吗?
一个号码K可能产生歧义当且仅当反转之后的号码是合法的数字K',并且满足1 ≤ K' ≤ N且K' ≠ K。
例如:
3没有歧义,因为贴反之后不是合法的数字。
100没有歧义,因为001以0开头,不是合法号码。
101也没有歧义,因为贴反之后还是101本身。
假设N=10000000,则1025689有歧义,因为贴反之后变成6895201。如果N=2000000,则1025689没有歧义,因为6895201大于N。
输入
一个整数N。(1 ≤ N ≤ 100000)
输出
从小到大输出1~N之间所有有歧义的号码。每个号码一行。
10样例输出
6 9
根据颠倒数字打表-->数字拆分-->使用表合并颠倒后的数字-->比较是否相等
package 蓝桥杯校赛2018; import java.util.Arrays; public class E { static int n = 100; static int k; static int[] r = new int[] { 0, 1, 2, -1, -1, 5, 9, -1, 8, 6 }; public static void main(String[] args) { for (int i = 1; i <= n; i++) { int[] na = split(i); // System.out.println(Arrays.toString(na)); if (na[na.length - 1] == 0) { // 首位为0 continue; } int j; int m = 0; for (j = na.length - 1; j >= 0; j--) { if (r[na[j]] == -1) { break; } m = m * 10 + r[na[j]]; } if (j == -1 && m != i) { System.out.println(i); } } } public static int length(int n) { int len = 0; while (n != 0) { n /= 10; len++; } return len; } public static int[] split(int n) { int[] ra = new int[length(n)]; int i = ra.length - 1; int r = n % 10; n /= 10; ra[i--] = r; while (n != 0) { r = n % 10; n /= 10; ra[i--] = r; } return ra; } }
描述
小Hi和他的小伙伴们一起写了很多代码。时间一久有些代码究竟是不是自己写的,小Hi也分辨不出来了。
于是他实现了一个分类算法,希望用机器学习实现自动分类。
为了评价这个分类算法的优劣,他选出了N份有标记的代码作测试集,并决定用F1 Score作为评价标准。
给出N份代码的实际作者是不是小Hi以及分类算法预测的结果,请你计算F1 Score。
输入
第一行包含一个整数N。(1 <= N <= 1000)
以下N行每行包含两个字符(+或-)。第一个字符代表这份代码的实际作者是不是小Hi(+代表是,-代表不是),第二个代表预测的作者是不是小Hi(+代表是,-代表不是)。
输出
一个百分数,X%,代表答案,X保留两位小数。
样例输入
4 + + + - - + - -
样例输出
50.00%
送分题,
package 蓝桥杯校赛2018; import java.util.Scanner; public class F { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n; int right = 0; n = in.nextInt(); for (int i = 0; i < n; i++) { if (in.next().equals(in.next())) { right++; } } System.out.format("%.2f%%", (double) right / n * 100); } }
描述
H国的身份证号码是一个N位的正整数(首位不能是0)。此外,由于防伪需要,一个N位正整数是合法的身份证号码当且仅当每位数字都小于等于K,并且任意相邻两位数字的乘积也小于等于K。
例如对于K=5, 101、211、210等都是合法的号码,而106、123、421等都是非法的号码。
给定一个正整数N以及K,请从小到大输出所有合法的号码。
输入
两个整数N和K。
对于80%的数据,1 ≤ N ≤ 6。
对于100%的数据,1 ≤ N ≤ 9,1 ≤ K ≤ 5。
输出
按从小到大的顺序输出所有合法的N位号码,每个号码占一行。
样例输入
2 4
样例输出
10 11 12 13 14 20 21 22 30 31 40 41
跟第一题差不多,排列组合,有一点不同,这里的数字可以重复出现
package 蓝桥杯校赛2018; import java.util.Scanner; public class G { static int[] a = new int[11]; static int k = 4, m = 2; public static void main(String[] args) { Scanner in = new Scanner(System.in); m = in.nextInt(); k = in.nextInt(); f(0); } static boolean is() { for (int i = 0; i < m; i++) { if (a[i] > k) { return false; } if (i > 0 && a[i] * a[i - 1] > k) { return false; } } return true; } static void f(int n) { if (n == m) { if (is()) { for (int i = 0; i < m; i++) { System.out.print(a[i] + " "); } System.out.println(); } return; } for (int i = 0; i <= k; i++) { if (n == 0 && i == 0) { //首位为0 continue; } a[n] = i; f(n + 1); } } }
描述
某人有N袋金币,其中第i袋内金币的数量是Ai。现在他决定选出2袋金币送给小Hi,再选2袋金币送给小Ho,同时使得小Hi和小Ho得到的金币总数相等。他想知道一共有多少种不同的选择方法。
具体来说,有多少种下标四元组(i, j, p, q)满足i, j, p, q两两不同,并且i < j, p < q, Ai + Aj = Ap + Aq。
例如对于数组A=[1, 1, 2, 2, 2],一共有12种选法:
i j p q 1 3 2 4 1 3 2 5 1 4 2 3 1 4 2 5 1 5 2 3 1 5 2 4 2 3 1 4 2 3 1 5 2 4 1 3 2 4 1 5 2 5 1 3 2 5 1 4
输入
第一行包含一个整数N。
第二行包含N个整数,A1, A2, A3 ... AN。
对于70%的数据,1 <= N <= 100
对于100%的数据,1 <= N <= 1000, 1 <= Ai <= 1000000
输出
不同选择的数目。
样例输入
5 1 1 2 2 2
样例输出
12
暴力for循环,还不知道会不会超时
package 蓝桥杯校赛2018; import java.util.Scanner; public class H { static int n; static int[] a = new int[1001]; static int count; public static void main(String[] args) { Scanner in = new Scanner(System.in); n = in.nextInt(); for (int i = 0; i < n; i++) { a[i] = in.nextInt(); } for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) { for (int q = 0; q < n - 1; q++) { if (q == i || q == j) { continue; } for (int z = q + 1; z < n; z++) { if (z == i || z == j) { continue; } if (a[i] + a[j] == a[q] + a[z]) { //System.out.println((i + 1) + " " + (j + 1) + " " + (q + 1) + " " + (z + 1)); count++; } } } } } System.out.println(count); } }