1.购物单(5/5分)
答案:5200
我在其他博主那里看到有一个大佬用excel方法计算很快,链接在下面啦
https://www.cnblogs.com/ljmzzyk/p/6918364.html
解题思路:
把题目给的清单复制然后格式化存入二维数组计算,花了二十多分钟T^T
代码如下:
public class a01_shopping {
public static void main(String[] args) {
long sum = 0;
double[][] a = {
{180.90,0.88},
{10.25,0.65},
{56.14,0.9},
{104.65,0.9},
{100.30,0.88},
{297.15,0.5},
{26.75,0.65},
{130.62,0.5},
{240.28,0.58},
{270.62,0.8},
{115.87,0.88},
{247.34,0.95},
{73.21,0.9},
{101.00,0.5},
{79.54,0.5},
{278.44,0.7},
{199.26,0.5},
{12.97,0.9},
{166.30,0.78},
{125.50,0.58},
{84.98,0.9},
{113.35,0.68},
{166.57,0.5},
{42.56,0.9},
{81.90,0.95},
{131.78,0.8},
{255.89,0.78},
{109.17,0.9},
{146.69,0.68},
{139.33,0.65},
{141.16,0.78},
{154.74,0.8},
{59.42,0.8},
{85.44,0.68},
{293.70,0.88},
{261.79,0.65},
{11.30,0.88},
{268.27,0.58},
{128.29,0.88},
{251.03,0.8},
{208.39,0.75},
{128.88,0.75},
{62.06,0.9},
{225.87,0.75},
{12.89,0.75},
{34.28,0.75},
{62.16,0.58},
{129.12,0.5},
{218.37,0.5},
{289.69,0.8}
};
for (int i = 0; i < a.length; i++) {
sum += a[i][0] * a[i][1];
}
System.out.println(sum + 90);
}
}
2.纸牌三角形(11/11分)
解题思路:
得到从1-9一共9个数字的全排列,然后判断这个数组的0,2,4,8索引的数字的和与0,1,3,5索引的数字的和与5,6,7,8索引上的数字的和是否相等,相等则计数器++,因为镜像和旋转不算所以统计完成后得到的结果要除以6,本题的难点在于怎么得到9个数字的全排列的所有可能性。
但是总共只有九个数字的话可以九层循环判断
代码如下:
public class a02_SanJiao {
public static void main(String[] args) {
int cnt = 0;
for (int a = 1; a < 10; a++) {
for (int b = 1; b < 10; b++) {
for (int c = 1; c < 10; c++) {
for (int d = 1; d < 10; d++) {
for (int e = 1; e < 10; e++) {
for (int f = 1; f < 10; f++) {
for (int g = 1; g < 10; g++) {
for (int h = 1; h < 10; h++) {
for (int i = 1; i < 10; i++) {
if(a != b && a != c && a != d && a != e &&
a != f && a != g && a != h && a != i &&
b != c && b != d && b != e && b != f &&
b != g && b != h && b != i && c != d &&
c != e && c != f && c != g && c != h &&
c != i && d != e && d != f && d != g &&
d != h && d != i && e != f && e != g &&
e != h && e != i && f != g && f != h &&
f != i && g != h && g != i && h != i &&
((a + c + e + i) == (a + b + d + f)) &&
((a + b + d + f) == (f + g + h + i))) {
cnt++;
}
}
}
}
}
}
}
}
}
}
System.out.println(cnt / 6);
}
}
让我用新学的全排列算法改进一下捏:(泰裤辣!!)
public class a02_SanJiao_02 {
static int cnt = 0;
public static void main(String[] args) {
int[] a = new int[9];
for (int i = 0; i < a.length; i++) {
a[i] = i;
}
f(a, 0);
System.out.println(cnt/6);
}
public static void f(int[] a,int n) {
if(n == a.length - 1) {
if(a[0] + a[1] + a[3] + a[5] == a[0] + a[2] + a[4] + a[8] &&
a[0] + a[2] + a[4] + a[8] == a[5] + a[6] + a[7] + a[8]) {
cnt++;
}
}
for (int i = n; i < a.length; i++) {
int t = a[i];a[i] = a[n];a[n] = t;
f(a,n+1);
t = a[i];a[i] = a[n];a[n] = t;
}
}
}
3.承压计算(0/13分)
X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。
每块金属原料的外形、尺寸完全一致,但重量不同。
金属材料被严格地堆放成金字塔形。
7
5 8
7 8 8
9 2 7 2
8 1 4 9 1
8 1 8 8 4 1
7 9 6 1 4 5 4
5 6 5 5 6 9 5 6
5 5 4 7 9 3 5 5 1
7 5 7 9 7 4 7 3 3 1
4 6 4 5 5 8 8 3 2 4 3
1 1 3 3 1 6 6 5 5 4 4 2
9 9 9 2 1 9 1 9 2 9 5 7 9
4 3 3 7 7 9 3 6 1 3 8 8 3 7
3 6 8 1 5 3 9 5 8 3 8 1 8 3 3
8 3 2 3 3 5 5 8 5 4 2 8 6 7 6 9
8 1 8 1 8 4 6 2 2 1 7 9 4 2 3 3 4
2 8 4 2 2 9 9 2 8 3 4 9 6 3 9 4 6 9
7 9 7 4 9 7 6 6 2 8 9 4 1 8 1 7 2 1 6
9 2 8 6 4 2 7 9 5 4 1 2 5 1 7 3 9 8 3 3
5 2 1 6 7 9 3 2 8 9 5 5 6 6 6 2 1 8 7 9 9
6 7 1 8 8 7 5 3 6 5 4 7 3 4 6 7 8 1 3 2 7 4
2 2 6 3 5 3 4 9 2 4 5 7 6 6 3 2 7 2 4 8 5 5 4
7 4 4 5 8 3 3 8 1 8 6 3 2 1 6 2 6 4 6 3 8 2 9 6
1 2 4 1 3 3 5 3 4 9 6 3 8 6 5 9 1 5 3 2 6 8 8 5 3
2 2 7 9 3 3 2 8 6 9 8 4 4 9 5 8 2 6 3 4 8 4 9 3 8 8
7 7 7 9 7 5 2 7 9 2 5 1 9 2 6 5 3 9 3 5 7 3 5 4 2 8 9
7 7 6 6 8 7 5 5 8 2 4 7 7 4 7 2 6 9 2 1 8 2 9 8 5 7 3 6
5 9 4 5 5 7 5 5 6 3 5 3 9 5 8 9 5 4 1 2 6 1 4 3 5 3 2 4 1
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
其中的数字代表金属块的重量(计量单位较大)。
最下一层的X代表30台极高精度的电子秤。
假设每块原料的重量都十分精确地平均落在下方的两个金属块上,
最后,所有的金属块的重量都严格精确地平分落在最底层的电子秤上。
电子秤的计量单位很小,所以显示的数字很大。
工作人员发现,其中读数最小的电子秤的示数为:2086458231
请你推算出:读数最大的电子秤的示数为多少?
注意:需要提交的是一个整数,不要填写任何多余的内容。
4.魔方状态(0/17分)
5.取数位(7/7分)
解题思路:
就是用递归解决取数位问题
代码如下:
f(x/10,k-1)
6.最大公共字串
6.最大公共子串(9/9分)
最大公共子串长度问题就是:
求两个串的所有子串中能够匹配上的最大长度是多少。
比如:“abcdkkk” 和 “baabcdadabc”,
可以找到的最长的公共子串是"abcd",所以最大公共子串长度为4。
下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。
请分析该解法的思路,并补全划线部分缺失的代码。
public class Main
{
static int f(String s1, String s2)
{
char[] c1 = s1.toCharArray();
char[] c2 = s2.toCharArray();
int[][] a = new int[c1.length+1][c2.length+1];
int max = 0;
for(int i=1; i<a.length; i++){
for(int j=1; j<a[i].length; j++){
if(c1[i-1]==c2[j-1]) {
a[i][j] = __________________; //填空
if(a[i][j] > max) max = a[i][j];
}
}
}
return max;
}
public static void main(String[] args){
int n = f("abcdkkk", "baabcdadabc");
System.out.println(n);
}
}
答案:a[i][j]=a[i-1][j-1]+1
解题思路:
一开始没看懂网上也找不到思路,然后在草稿本上自己模拟了一下发现马上清晰了,草稿如图
7.日期问题(9.5/19)
解题思路:
没什么思路,用的最蠢的方法,写完以后发现只能过50%样例,有两方面缺陷:
(1)没有考虑到闰年2月有29天
(2)输出的结果没有排序
代码:
import java.util.Scanner;
public class a06_Date {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
int[] a = {s.charAt(0) - '0',s.charAt(1) - '0'};//年
int[] b = {s.charAt(3) - '0',s.charAt(4) - '0'};//月
int[] c = {s.charAt(6) - '0',s.charAt(7) - '0'};//日
String[] sArr = new String[3];
//aa/bb/cc ->年/月/日
if(getSum(a) >= 0 && getSum(a) <= 59) {//21世纪
if(checkMonth(b)) {
if(checkDay(getSum(b), c)) {
sArr[0] = "20" + a[0] + a[1] + "-" + b[0] + b[1] + "-" + c[0] + c[1];
}
}
}
else {//20世纪
if(checkMonth(b)) {
if(checkDay(getSum(b), c)) {
sArr[0] = "19" + a[0] + a[1] + "-" + b[0] + b[1] + "-" + c[0] + c[1];
}
}
}
//aa/bb/cc ->月/日/年
if(getSum(c) >= 0 && getSum(c) <= 59) {//21世纪
if(checkMonth(a)) {
if(checkDay(getSum(a), b)) {
sArr[1] = "20" + c[0] + c[1] + "-" + a[0] + a[1] + "-" + b[0] + b[1];
}
}
}
else {//20世纪
if(checkMonth(c)) {
if(checkDay(getSum(c), b)) {
sArr[1] = "19" + c[0] + c[1] + "-" + a[0] + a[1] + "-" + b[0] + b[1];
}
}
}
//aa/bb/cc ->日/月/年
if(getSum(c) >= 0 && getSum(c) <= 59) {//21世纪
if(checkMonth(b)) {
if(checkDay(getSum(b), a)) {
sArr[2] = "20" + b[0] + b[1] + "-" + a[0] + a[1] + "-" + c[0] + c[1];
}
}
}
else {//20世纪
if(checkMonth(c)) {
if(checkDay(getSum(c), b)) {
sArr[2] = "19" + b[0] + b[1] + "-" + a[0] + a[1] + "-" + c[0] + c[1];
}
}
}
for (int i = 0; i < sArr.length; i++) {
if(sArr[i] != null) {
System.out.println(sArr[i]);
}
}
}
public static int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum = sum * 10 +arr[i];
}
return sum;
}
//检查某个日期是否合规
//年:1960-2059(年份后两位可以从00-99)
//月:01-12
//日:01-28,29,30,31
//1.先判断三个时间作为月份是否满足条件
public static boolean checkMonth(int[] arr) {
if(arr[0] * 10 + arr[1] >= 1 && arr[0] * 10 + arr[1] <= 12) {
return true;
}
else {
return false;
}
}
//2.再判断三个时间作为天数能不能满足条件
public static boolean checkDay(int m,int[] arr) {//m表示月份
if(m == 1 || m == 3 || m == 5 || m== 7 || m== 8 || m== 10 || m== 12) {
if(arr[0] * 10 + arr[1] >= 1 && arr[0] * 10 + arr[1] <= 31) {
return true;
}
else {
return false;
}
}
else if(m == 4 || m== 6 || m== 9 || m== 11) {
if(arr[0] * 10 + arr[1] >= 1 && arr[0] * 10 + arr[1] <= 30) {
return true;
}
else {
return false;
}
}
else {
if(arr[0] * 10 + arr[1] >= 1 && arr[0] * 10 + arr[1] <= 29) {
return true;
}
else {
return false;
}
}
}
}
8.包子凑数(2.3/21分)
解题思路:
没有思路且看不懂答案。但是题目说了有一种情况是输出INF,所以我写的代码是直接输出INF,然后骗了一个测试点的分。
9.分巧克力(17.3/23分)
解题思路:最大边长默认从1开始,然后看看这样切割能否满足条件,满足则边长加一,直到切割不出需要的数量,返回这个边长减一。(这是最基础的思路但是只能拿62.5%的分数)
代码如下:
import java.util.Scanner;
public class a08_分巧克力 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();//n块巧克力
int k = sc.nextInt();//需要分成k块巧克力
int[][] a = new int[n][2];//n行2列的矩阵 第一列表示长,第二列表示宽
for (int i = 0; i < a.length; i++) {
a[i][0] = sc.nextInt();//长
a[i][1] = sc.nextInt();//宽
}
int t = 1;//边长
while(true) {
int sum = 0;
for(int i = 0; i < a.length; i++) {
int len = a[i][0] / t;
int wid = a[i][1] / t;
sum += len * wid;
}
if(sum <= k) {
t--;
break;
}
else {
t++;
}
}
System.out.println(t);
}
}
解题思路(二分法改进):(75%得分)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();//n块巧克力
int k = sc.nextInt();//需要分成k块巧克力
int[][] a = new int[n][2];//n行2列的矩阵 第一列表示长,第二列表示宽
int max = 0;
for (int i = 0; i < a.length; i++) {
a[i][0] = sc.nextInt();//长
a[i][1] = sc.nextInt();//宽
if(a[i][0] > max) {
max = a[i][0];
}
if(a[i][1] > max) {
max = a[i][1];
}
}
int t = max;//边长
while(true) {
if(getSum(a, t) < k) {//边长为t时分出的巧克力过少
t /= 2;
}
else if(getSum(a, t) >= k) {
if(getSum(a, t + 1) < k) {
break;
}
else {
t++;
}
}
}
System.out.println(t);
}
public static int getSum(int[][] a,int t) {//边长为t的情况下能分出多少块巧克力
int sum = 0;
for(int i = 0; i < a.length; i++) {
int len = a[i][0] / t;
int wid = a[i][1] / t;
sum += len * wid;
}
return sum;
}
}
10.K倍区间(9.4/25分)
解题思路:暴力。没有想到优化方法,只能得3/8分数。
代码如下,仅供参考:
import java.util.Scanner;
public class a10_k倍区间 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();//对比数
int[] a = new int[n];
for (int i = 0; i < a.length; i++) {
a[i] = sc.nextInt();
}
int cnt = 0;
for (int i = 0; i < a.length; i++) {
int sum = 0;
for (int j = i; j < a.length; j++) {
sum += a[j];
if(sum % k == 0) {
cnt++;
}
}
}
System.out.println(cnt);
}
}
=======================2/29日更新,黑色分数为本次更新内容====================
总分23,惨不忍睹,完全做不下去哇,先往后刷题再回过头学习这些知识点吧。
=======================3/10日更新,红色分数为本次更新内容====================
这次二刷题目发现很难的题目其实也不是完全没有得分点,但是第一次刷的时候看到一些题目直接放弃了思考,这是不可取的!!! 比赛的时候其实很多题目都可以拿到部分分数,切记不能浮躁,保持冷静。