Skip to content

Commit 6c437d2

Browse files
committed
modify code
1 parent fabeb48 commit 6c437d2

14 files changed

+894
-17
lines changed

src/followup/Code01_Cola.java

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package followup;
2+
3+
public class Code01_Cola {
4+
/*
5+
* 买饮料 时间限制: 3000MS 内存限制: 589824KB 题目描述:
6+
* 游游今年就要毕业了,和同学们在携程上定制了日本毕业旅行。愉快的一天行程结束后大家回到了酒店房间,这时候同学们都很口渴,
7+
* 石头剪刀布选出游游去楼下的自动贩卖机给大家买可乐。 贩卖机只支持硬币支付,且收退都只支持10 ,50,100
8+
* 三种面额。一次购买行为只能出一瓶可乐,且每次购买后总是找零最小枚数的硬币。(例如投入100圆,可乐30圆,则找零50圆一枚,10圆两枚)
9+
* 游游需要购买的可乐数量是 m,其中手头拥有的 10,50,100 面额硬币的枚数分别是 a,b,c,可乐的价格是x(x是10的倍数)。
10+
* 如果游游优先使用大面额购买且钱是够的情况下,请计算出需要投入硬币次数? 输入描述 依次输入, 需要可乐的数量为 m 10元的张数为 a 50元的张数为 b
11+
* 100元的张树为 c 1瓶可乐的价格为 x 输出描述 输出当前金额下需要投入硬币的次数
12+
* 例如需要购买2瓶可乐,每瓶可乐250圆,手里有100圆3枚,50圆4枚,10圆1枚。 购买第1瓶投递100圆3枚,找50圆 购买第2瓶投递50圆5枚
13+
* 所以是总共需要操作8次金额投递操作 样例输入 2 1 4 3 250 样例输出 8
14+
*/
15+
16+
// 暴力尝试,为了验证正式方法而已
17+
public static int right(int m, int a, int b, int c, int x) {
18+
int[] qian = { 100, 50, 10 };
19+
int[] zhang = { c, b, a };
20+
int puts = 0;
21+
while (m != 0) {
22+
int cur = buy(qian, zhang, x);
23+
if (cur == -1) {
24+
return -1;
25+
}
26+
puts += cur;
27+
m--;
28+
}
29+
return puts;
30+
}
31+
32+
public static int buy(int[] qian, int[] zhang, int rest) {
33+
int first = -1;
34+
for (int i = 0; i < 3; i++) {
35+
if (zhang[i] != 0) {
36+
first = i;
37+
break;
38+
}
39+
}
40+
if (first == -1) {
41+
return -1;
42+
}
43+
if (qian[first] >= rest) {
44+
zhang[first]--;
45+
giveRest(qian, zhang, first + 1, qian[first] - rest, 1);
46+
return 1;
47+
} else {
48+
zhang[first]--;
49+
int next = buy(qian, zhang, rest - qian[first]);
50+
if (next == -1) {
51+
return -1;
52+
}
53+
return 1 + next;
54+
}
55+
}
56+
57+
// 正式的方法
58+
public static int putTimes(int m, int a, int b, int c, int x) {
59+
// 0 1 2
60+
int[] qian = { 100, 50, 10 };
61+
int[] zhang = { c, b, a };
62+
// 总共需要多少次投币
63+
int puts = 0;
64+
// 之前面值的钱还剩下多少总钱数
65+
int preQianRest = 0;
66+
// 之前面值的钱还剩下多少总张数
67+
int preQianZhang = 0;
68+
for (int i = 0; i < 3 && m != 0; i++) {
69+
// 要用之前剩下的钱、当前面值的钱,共同买第一瓶可乐
70+
// 之前的面值剩下多少钱,是preQianRest
71+
// 之前的面值剩下多少张,是preQianZhang
72+
// 之所以之前的面值会剩下来,一定是剩下的钱,一直攒不出一瓶可乐的单价
73+
// 当前的面值付出一些钱+之前剩下的钱,此时有可能凑出一瓶可乐来
74+
// 那么当前面值参与搞定第一瓶可乐,需要掏出多少张呢?就是curQianFirstBuyZhang
75+
int curQianFirstBuyZhang = (x - preQianRest + qian[i] - 1) / qian[i];
76+
if (zhang[i] >= curQianFirstBuyZhang) { // 如果之前的钱和当前面值的钱,能凑出第一瓶可乐
77+
// 凑出来了一瓶可乐也可能存在找钱的情况,
78+
giveRest(qian, zhang, i + 1, (preQianRest + qian[i] * curQianFirstBuyZhang) - x, 1);
79+
puts += curQianFirstBuyZhang + preQianZhang;
80+
zhang[i] -= curQianFirstBuyZhang;
81+
m--;
82+
} else { // 如果之前的钱和当前面值的钱,不能凑出第一瓶可乐
83+
preQianRest += qian[i] * zhang[i];
84+
preQianZhang += zhang[i];
85+
continue;
86+
}
87+
// 凑出第一瓶可乐之后,当前的面值有可能能继续买更多的可乐
88+
// 以下过程就是后续的可乐怎么用当前面值的钱来买
89+
// 用当前面值的钱,买一瓶可乐需要几张
90+
int curQianBuyOneColaZhang = (x + qian[i] - 1) / qian[i];
91+
// 用当前面值的钱,一共可以搞定几瓶可乐
92+
int curQianBuyColas = Math.min(zhang[i] / curQianBuyOneColaZhang, m);
93+
// 用当前面值的钱,每搞定一瓶可乐,收货机会吐出多少零钱
94+
int oneTimeRest = qian[i] * curQianBuyOneColaZhang - x;
95+
// 每次买一瓶可乐,吐出的找零总钱数是oneTimeRest
96+
// 一共买的可乐数是curQianBuyColas,所以把零钱去提升后面几种面值的硬币数,
97+
// 就是giveRest的含义
98+
giveRest(qian, zhang, i + 1, oneTimeRest, curQianBuyColas);
99+
// 当前面值去搞定可乐这件事,一共投了几次币
100+
puts += curQianBuyOneColaZhang * curQianBuyColas;
101+
// 还剩下多少瓶可乐需要去搞定,继续用后面的面值搞定去吧
102+
m -= curQianBuyColas;
103+
// 当前面值可能剩下若干张,要参与到后续买可乐的过程中去,
104+
// 所以要更新preQianRest和preQianZhang
105+
zhang[i] -= curQianBuyOneColaZhang * curQianBuyColas;
106+
preQianRest = qian[i] * zhang[i];
107+
preQianZhang = zhang[i];
108+
}
109+
return m == 0 ? puts : -1;
110+
}
111+
112+
public static void giveRest(int[] qian, int[] zhang, int i, int oneTimeRest, int times) {
113+
for (; i < 3; i++) {
114+
zhang[i] += (oneTimeRest / qian[i]) * times;
115+
oneTimeRest %= qian[i];
116+
}
117+
}
118+
119+
public static void main(String[] args) {
120+
int testTime = 1000;
121+
int zhangMax = 10;
122+
int colaMax = 10;
123+
int priceMax = 20;
124+
System.out.println("如果错误会打印错误数据,否则就是正确");
125+
System.out.println("test begin");
126+
for (int i = 0; i < testTime; i++) {
127+
int m = (int) (Math.random() * colaMax);
128+
int a = (int) (Math.random() * zhangMax);
129+
int b = (int) (Math.random() * zhangMax);
130+
int c = (int) (Math.random() * zhangMax);
131+
int x = ((int) (Math.random() * priceMax) + 1) * 10;
132+
int ans1 = putTimes(m, a, b, c, x);
133+
int ans2 = right(m, a, b, c, x);
134+
if (ans1 != ans2) {
135+
System.out.println("int m = " + m + ";");
136+
System.out.println("int a = " + a + ";");
137+
System.out.println("int b = " + b + ";");
138+
System.out.println("int c = " + c + ";");
139+
System.out.println("int x = " + x + ";");
140+
break;
141+
}
142+
}
143+
System.out.println("test end");
144+
}
145+
146+
}

src/followup/Code02_Drive.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package followup;
2+
3+
public class Code02_Drive {
4+
5+
/*
6+
* 司机调度 时间限制: 3000MS 内存限制: 589824KB 题目描述:
7+
* 正值下班高峰时期,现有可载客司机数2N人,调度中心将调度相关司机服务A、B两个出行高峰区域。 第 i 个司机前往服务A区域可得收入为
8+
* income[i][0],前往服务B区域可得收入为 income[i][1]。
9+
* 返回将每位司机调度完成服务后,所有司机总可得的最高收入金额,要求每个区域都有 N 位司机服务。 输入描述 10 20 20 40 # 如上:
10+
* 第一个司机服务 A 区域,收入为 10元 第一个司机服务 B 区域,收入为 20元 第二个司机服务 A 区域,收入为 20元 第二个司机服务 B
11+
* 区域,收入为 40元 输入参数以 '#' 结束输入 输出描述 最高总收入为 10 + 40= 50,每个区域都有一半司机服务
12+
* 参数及相关数据异常请输出:error 样例输入 : 10 30 100 200 150 50 60 20 # 样例输出 440
13+
*/
14+
15+
// 给定一个N*2的正数矩阵matix,N一定是偶数,可以保证。
16+
// 一定要让A区域分到N/2个司机,让B区域也分到N/2个司机
17+
// 返回最大的总收益
18+
public static int maxMoney(int[][] matrix) {
19+
return process(matrix, 0, matrix.length / 2);
20+
}
21+
22+
// 从i开始到最后所有的司机,在A区域还有aRest个名额的情况下,返回最优分配的收益
23+
public static int process(int[][] matrix, int i, int aRest) {
24+
if (aRest < 0) {
25+
return -1;
26+
}
27+
if (i == matrix.length) {
28+
return aRest == 0 ? 0 : -1;
29+
}
30+
int goToA = -1;
31+
int nextA = process(matrix, i + 1, aRest - 1);
32+
if (nextA != -1) {
33+
goToA = matrix[i][0] + nextA;
34+
}
35+
int goToB = -1;
36+
int nextB = process(matrix, i + 1, aRest);
37+
if (nextB != -1) {
38+
goToB = matrix[i][1] + nextB;
39+
}
40+
return Math.max(goToA, goToB);
41+
}
42+
43+
public static void main(String[] args) {
44+
int[][] matrix = { { 10, 20 }, { 20, 40 } };
45+
46+
System.out.println(maxMoney(matrix));
47+
}
48+
49+
}

src/followup/Code03_Array.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package followup;
2+
3+
public class Code03_Array {
4+
5+
public static int findError(String[] contents) {
6+
if (contents == null || contents.length == 0) {
7+
return 0;
8+
}
9+
String arrName = contents[0].substring(0, contents[0].indexOf("["));
10+
int arrSize = Integer.valueOf(contents[0].substring(contents[0].indexOf("[") + 1, contents[0].indexOf("]")));
11+
int[] arr = new int[arrSize];
12+
for (int i = 1; i < contents.length; i++) {
13+
String[] parts = contents[i].replace(" ", "").split("=");
14+
String left = parts[0].replace(arrName, "");
15+
left = left.substring(1, left.length() - 1);
16+
String right = parts[1].replace(arrName, "");
17+
Integer leftIndex = value(left, arr);
18+
Integer rightValue = value(right, arr);
19+
if (leftIndex == null || rightValue == null) {
20+
return i;
21+
}
22+
if (leftIndex < 0 || leftIndex >= arrSize) {
23+
return i;
24+
}
25+
arr[leftIndex] = rightValue;
26+
}
27+
return 0;
28+
}
29+
30+
public static Integer value(String str, int[] arr) {
31+
int value = Integer.valueOf(str.replace("[", "").replace("]", ""));
32+
int levels = str.lastIndexOf("[") + 1;
33+
for (int i = 0; i < levels; i++) {
34+
if (value < 0 || value >= arr.length) {
35+
return null;
36+
}
37+
value = arr[value];
38+
}
39+
return value;
40+
}
41+
42+
public static void main(String[] args) {
43+
String[] contents = { "arr[7]", "arr[0]=6", "arr[1]=3", "arr[2]=1", "arr[3]=2", "arr[4]=4", "arr[5]=0",
44+
"arr[6]=5", "arr[arr[1]]=3", "arr[arr[arr[arr[5]]]]=arr[arr[arr[3]]]", "arr[arr[4]]=arr[arr[arr[0]]]",
45+
"arr[arr[1]] = 7", "arr[0] = arr[arr[arr[1]]]" };
46+
System.out.println(findError(contents));
47+
48+
}
49+
50+
}

src/followup/Code04_Painting.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package followup;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public class Code04_Painting {
7+
// N * M的棋盘
8+
// 每种颜色的格子数必须相同的
9+
// 相邻格子染的颜色必须不同
10+
// 所有格子必须染色
11+
// 返回至少多少种颜色可以完成任务
12+
13+
public static int minColors(int N, int M) {
14+
for (int i = 2; i < N * M; i++) {
15+
int[][] matrix = new int[N][M];
16+
// 下面这一句可知,需要的最少颜色数i,一定是N*M的某个因子
17+
if ((N * M) % i == 0 && can(matrix, N, M, i)) {
18+
return i;
19+
}
20+
}
21+
return N * M;
22+
}
23+
24+
// 在matrix上染色,返回只用pNum种颜色是否可以做到要求
25+
public static boolean can(int[][] matrix, int N, int M, int pNum) {
26+
int all = N * M;
27+
int every = all / pNum;
28+
ArrayList<Integer> rest = new ArrayList<>();
29+
rest.add(0);
30+
for (int i = 1; i <= pNum; i++) {
31+
rest.add(every);
32+
}
33+
return process(matrix, N, M, pNum, 0, 0, rest);
34+
}
35+
36+
public static boolean process(int[][] matrix, int N, int M, int pNum, int row, int col, List<Integer> rest) {
37+
if (row == N) {
38+
return true;
39+
}
40+
if (col == M) {
41+
return process(matrix, N, M, pNum, row + 1, 0, rest);
42+
}
43+
int left = col == 0 ? 0 : matrix[row][col - 1];
44+
int up = row == 0 ? 0 : matrix[row - 1][col];
45+
for (int color = 1; color <= pNum; color++) {
46+
if (color != left && color != up && rest.get(color) > 0) {
47+
int count = rest.get(color);
48+
rest.set(color, count - 1);
49+
matrix[row][col] = color;
50+
if (process(matrix, N, M, pNum, row, col + 1, rest)) {
51+
return true;
52+
}
53+
rest.set(color, count);
54+
matrix[row][col] = 0;
55+
}
56+
}
57+
return false;
58+
}
59+
60+
public static void main(String[] args) {
61+
// 根据代码16行的提示,打印出答案,看看是答案是哪个因子
62+
for (int N = 2; N < 10; N++) {
63+
for (int M = 2; M < 10; M++) {
64+
System.out.println("N = " + N);
65+
System.out.println("M = " + M);
66+
System.out.println("ans = " + minColors(N, M));
67+
System.out.println("===========");
68+
}
69+
}
70+
// 打印答案,分析可知,是N*M最小的质数因子,原因不明,也不重要
71+
// 反正打表法猜出来了
72+
}
73+
74+
}

0 commit comments

Comments
 (0)