-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIn1.cpp
174 lines (152 loc) · 3.09 KB
/
In1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include<unordered_set>
#include<algorithm>
#include<iostream>
using namespace std;
class In1 {
public:
int help1(int m, int n, int k){
//http://blog.csdn.net/xiaqunfeng123/article/details/51765987
//代码和网上的不同
// 解题思路
// 简单来说,就是不停的从量杯m往n中倒水,然后n清空的过程。
// 如果此时m == k,结束;
// 若不相等,从m中倒水到n中直至n满,或者直至m空;
// 若n满,m != k,则清空n,重复上述动作。
int a = 0, b = 0;
int res = 0;
unordered_set<int> s;//跟踪a中水当前高度,若出现重复,则无解
//初始化情形
a = m; ++res;//倒满a
if (a == k) {
return res;
}
s.insert(a);
a = m - n; b = n; ++res;//a向b加水直到b满
if (a == k) {
return res;
}
s.insert(a);
while (a != k){
// while(a>n){
// b=0;++res;//倒空b
// b=n;a-=n;++res;//a向b加水直到b满
// if (a==k) {
// return res;
// }
// if (s.contains(a)) {
// return -1;
// }
// s.add(a);
//
// }
//这一段和上面的注释部分等价,但是因为知道k<n,直接用除法即可
if (a>n) {
int c = a / n;
a = a%n;
if (a == 0) {//针对a是n的倍数情况
a = n; --c;
}
res += c * 2;
if (a == k) {
return res;
}
if (s.find(a)!=s.end()) {
return -1;
}
s.insert(a);
}
b = 0; ++res;//倒空b
b = a; a = 0; ++res;//a全部倒给b
a = m; ++res;//倒满a
a -= n - b; b = n; ++res;//a向b加水直到b满
if (s.find(a)!=s.end()) {
return -1;
}
s.insert(a);
}
return res;
}
int help2(int m, int n, int k){
int a = 0, b = 0;
int res = 0;
unordered_set<int> s;//跟踪a中水当前高度,若出现重复,则无解
//初始化情形
a = m; ++res;//倒满a
if (a == k) {
return res;
}
s.insert(a);
a = m - n; b = n; ++res;//a向b加水直到b满
if (a == k) {
return res;
}
s.insert(a);
while (a != k){
while (a>n){
b = 0; ++res;//倒空b
b = n; a -= n; ++res;//a向b加水直到b满
if (a == k) {
return res;
}
if (s.find(a)!=s.end()) {
return -1;
}
s.insert(a);
}
// if (a>n) {
// int c=a/n;
// a=a%n;
// if (a==0) {
// a=n;--c;
// }
// res+=c*2;
// if (a==k) {
// return res;
// }
// if (s.contains(a)) {
// return -1;
// }
// s.add(a);
// }
b = 0; ++res;//倒空b
b = a; a = 0; ++res;//a全部倒给b
a = m; ++res;//倒满a
a -= n - b; b = n; ++res;//a向b加水直到b满
if (s.find(a)!=s.end()) {
return -1;
}
s.insert(a);
}
return res;
}
int MinSteps(int m, int n, int k){
//负数或0
if (m < 0 || n < 0 || k < 0)
return -1;
//m不是最大的
if (m < n || m < k)
return -1;
//m 和 k相等,只需要一次操作即可
if (m == k){
if (k == 0) return 0;
else return 1;
}
// 不断加满n,然后倒入m
if (k%n == 0)
return min(2 * (k / n), help2(m, n, k));
if (k<n) {
//help1 和 help2不同的只在注释掉的部分
//k<n时直接用除法解决,否则,要不断地从a中减掉n
return help1(m, n, k);
}
else {
return help2(m, n, k);
}
}
};
void main_In1(){
In1 in1;
//int m = 13, n = 7, k = 2;
int m = 9, n = 8, k = 4;
cout << in1.MinSteps(m, n, k) << endl;
}