Skip to content

Commit f7f58e2

Browse files
committed
upload
1 parent be0471c commit f7f58e2

File tree

23 files changed

+1397
-24
lines changed

23 files changed

+1397
-24
lines changed

2.C程序设计进阶/week3/作业/README.md

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,7 @@ olleh .dlrow
8787
### 样例输入
8888

8989
```
90-
1
91-
92-
93-
94-
95-
96-
97-
98-
9990
5
100-
101-
102-
103-
104-
105-
10691
```
10792

10893
### 样例输出

3.C++程序设计/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# C++程序设计

3.C++程序设计/week4/编程练习/大整数的加减乘除.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ using namespace std;
66
class BigInt
77
{
88
private:
9-
string num;
10-
char sign;
9+
string num; // 数值
10+
char sign; // 正负
1111
public:
12-
BigInt(string n = "0");
13-
BigInt operator+(const BigInt &bi);
14-
BigInt operator-(const BigInt &bi);
15-
BigInt operator*(const BigInt &bi);
16-
BigInt operator/(const BigInt &bi);
17-
friend ostream& operator<<(ostream &o, const BigInt &b);
12+
BigInt(string n = "0"); // 构造函数,缺省为0
13+
BigInt operator+(const BigInt &bi); // 大整数加法
14+
BigInt operator-(const BigInt &bi); // 大整数减法
15+
BigInt operator*(const BigInt &bi); // 大整数乘法
16+
BigInt operator/(const BigInt &bi); // 大整数除法
17+
friend ostream& operator<<(ostream &o, const BigInt &b); // 大整数输出
1818
};
1919

2020
BigInt::BigInt(string n)

4.算法基础/week2/README.md

Lines changed: 294 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,297 @@
3535
- 根据PRIM0, PRIM1 , …, PRIMk, 寻找比PRIMk大的最小素数PRIMk+1
3636
- 如果PRIMk+1大于N, 则PRIMk是我们需要找的素数, 否则继续寻找
3737
- 解空间:2到N的所有素数
38-
- 减小搜索空间:排除所有奇数
38+
- 减小搜索空间:排除所有奇数
39+
40+
## 熄灯问题
41+
42+
有一个由按钮组成的矩阵,其中每行有6个按钮, 共5行,每个按钮的位置上有一盏灯,当按下一个按钮后,该按钮以及周围位置(上边, 下边, 左边, 右边)的灯都会改变一次。请你写一个程序, 确定需要按下哪些按钮, 恰好使得所 有的灯都熄灭
43+
44+
### 输入
45+
46+
- 第一行是一个正整数N, 表示需要解决的案例数
47+
- 每个案例由5行组成, 每一行包括6个数字
48+
- 这些数字以空格隔开, 可以是0或1
49+
- 0 表示灯的初始状态是熄灭的
50+
- 1 表示灯的初始状态是点亮的
51+
52+
### 输出
53+
54+
- 对每个案例, 首先输出一行, 输出字符串 “PUZZLE #m”, 其中m是该案例的序号
55+
- 接着按照该案例的输入格式输出5行
56+
- 1 表示需要把对应的按钮按下
57+
- 0 表示不需要按对应的按钮
58+
- 每个数字以一个空格隔开
59+
60+
### 解题分析
61+
62+
枚举法。
63+
64+
解空间:5x6的0-1矩阵的所有可能情况:$2^{30}$种可能
65+
66+
减小搜索空间:
67+
68+
- 当第一行的按钮情况确定以后,要使第一行全熄灭,第二行已经被确定,同理剩余几行都被确定了
69+
- 因此枚举的情况减小为第一行的所有可能:$2^6 = 64$
70+
- 最后只需验证最后一行
71+
72+
合适的搜索顺序:
73+
74+
- 六个循环嵌套
75+
- 把第一行当作二进制数,每次加1,然后处理进位✓
76+
77+
### 解答程序
78+
79+
```c++
80+
#include <iostream>
81+
using namespace std;
82+
83+
int puzzle[6][8], press[6][8];
84+
85+
// 初始化数组和处理输入
86+
void init()
87+
{
88+
for (int i = 1; i < 6; i++)
89+
{
90+
for (int j = 1; j < 7; j++)
91+
{
92+
cin >> puzzle[i][j];
93+
}
94+
}
95+
for (int j = 0; j < 8; j++)
96+
{
97+
press[0][j] = 0;
98+
}
99+
for (int i = 0; i < 6; i++)
100+
{
101+
press[i][0] = 0;
102+
press[i][7] = 0;
103+
}
104+
}
105+
106+
// 验证答案是否正确,主要验证最后一行
107+
bool guess()
108+
{
109+
for (int j = 1; j < 7; j++)
110+
{
111+
if ((press[5][j - 1] + press[5][j] + press[5][j + 1] + press[4][j]) % 2 != puzzle[5][j])
112+
return false;
113+
}
114+
return true;
115+
}
116+
117+
// 根据第一行的枚举更新剩余几行
118+
void update()
119+
{
120+
for (int i = 1; i < 5; i++)
121+
{
122+
for (int j = 1; j < 7; j++)
123+
{
124+
press[i + 1][j] = (puzzle[i][j] + press[i][j] + press[i][j - 1] + press[i][j + 1] + press[i - 1][j]) % 2;
125+
}
126+
}
127+
}
128+
129+
// 枚举第一行的所有情况,直到得出答案
130+
void enumerate()
131+
{
132+
// 初始情况
133+
for (int j = 1; j < 7; j++)
134+
{
135+
press[1][j] = 0;
136+
}
137+
update();
138+
while (!guess())
139+
{
140+
press[1][1]++;
141+
int i = 1;
142+
while (press[1][i] > 1) // 进位
143+
{
144+
press[1][i] = 0;
145+
press[1][++i]++;
146+
}
147+
update();
148+
}
149+
}
150+
151+
int main()
152+
{
153+
int ncase;
154+
cin >> ncase;
155+
for (int i = 0; i < ncase; i++)
156+
{
157+
cout << "PUZZLE #" << i + 1 << endl;
158+
init();
159+
enumerate();
160+
// 输出结果
161+
for (int i = 1; i < 6; i++)
162+
{
163+
for (int j = 1; j < 7; j++)
164+
{
165+
cout << press[i][j] << " ";
166+
}
167+
cout << endl;
168+
}
169+
}
170+
}
171+
```
172+
173+
## 讨厌的青蛙
174+
175+
### 问题描述
176+
177+
有一种小青蛙,每到晚上,这种青蛙会跳跃稻田,从而踩踏稻子。农民早上看到被踩踏的稻子, 希望找到造成最大损害的那只青蛙经过的路径。每只青蛙总是沿着一条直线跳跃稻田,且每次跳跃的距离都相同。请写一个程序,确定在各条青蛙行走路径中, 踩踏水稻最多的那一条上,有多少颗水稻被踩踏。
178+
179+
### 输入
180+
181+
- 从标准输入设备上读入数据
182+
- 第一行上两个整数R, C, 分别表示稻田中水稻的行数和 列数, 1≤R, C≤5000
183+
- 第二行是一个整数N, 表示被踩踏的水稻数量, 3≤N≤5000
184+
- 在剩下的N行中, 每行有两个整数, 分别是一颗被踩踏水 稻的行号(1~R)和列号(1~C), 两个整数用一个空格隔开
185+
- 且每棵被踩踏水稻只被列出一次
186+
187+
### 输出
188+
189+
- 从标准输出设备上输出一个整数
190+
- 如果在稻田中存在青蛙行走路径, 则输出包含最多水稻 的青蛙行走路径中的水稻数量, 否则输出0
191+
192+
### 样例输入
193+
194+
```
195+
6 7
196+
14
197+
2 1
198+
6 6
199+
4 2
200+
2 5
201+
2 6
202+
2 7
203+
3 4
204+
6 1
205+
6 2
206+
2 3
207+
6 3
208+
6 4
209+
6 5
210+
6 7
211+
```
212+
213+
### 样例输出
214+
215+
```
216+
7
217+
```
218+
219+
### 解题思路
220+
221+
解空间:所有可能的直线路径
222+
223+
减小搜索空间:
224+
225+
- 每条青蛙行走路径中至少有3颗水稻(看了半天题目没搞懂为什么,就当题设吧)
226+
- 路径的起点和终点在稻田外
227+
228+
枚举方法:
229+
230+
- 枚举所有点(低效,不可行)
231+
- 任取两个点作为稻田内的起始点,计算步长得到整条路径
232+
- `sort`
233+
- `binary_search`
234+
235+
### 解题程序
236+
237+
```c++
238+
#include <iostream>
239+
#include <algorithm>
240+
using namespace std;
241+
242+
int row, col, numOfPoints;
243+
244+
struct Point
245+
{
246+
int x, y;
247+
};
248+
Point points[5001];
249+
250+
bool operator<(const Point &p1, const Point &p2)
251+
{
252+
if (p1.x == p2.x)
253+
{
254+
return p1.y < p2.y;
255+
}
256+
else
257+
{
258+
return p1.x < p2.x;
259+
}
260+
}
261+
262+
int searchPath(Point p, int dx, int dy)
263+
{
264+
Point tmp;
265+
int steps;
266+
tmp.x = p.x + dx;
267+
tmp.y = p.y + dy;
268+
steps = 2;
269+
while (tmp.x <= row && tmp.x >= 1 && tmp.y <= col && tmp.y >= 1)
270+
{
271+
if (binary_search(points, points + numOfPoints, tmp))
272+
{
273+
tmp.x += dx;
274+
tmp.y += dy;
275+
steps++;
276+
}
277+
else
278+
{
279+
steps = 0;
280+
break;
281+
}
282+
}
283+
return steps;
284+
}
285+
286+
int main()
287+
{
288+
289+
cin >> row >> col >> numOfPoints;
290+
291+
for (int i = 0; i < numOfPoints; i++)
292+
{
293+
cin >> points[i].x >> points[i].y;
294+
}
295+
sort(points, points + numOfPoints);
296+
297+
int maxStep = 2;
298+
for (int i = 0; i < numOfPoints - 1; i++)
299+
{
300+
for (int j = i + 1; j < numOfPoints; j++)
301+
{
302+
int dx = points[j].x - points[i].x;
303+
int dy = points[j].y - points[i].y;
304+
// 起点在稻田内,更换第二个点
305+
if (points[i].x - dx >= 1 && points[i].x - dx <= row && points[i].y - dy >= 1 && points[i].y - dy <= col)
306+
{
307+
continue;
308+
}
309+
// 当走 maxStep 时在x方向已经走出稻田,更换第一个点
310+
if (points[i].x + (maxStep - 1) * dx > row)
311+
{
312+
break;
313+
}
314+
// 当走 maxStep 时在y方向已经走出稻田,更换第二个点
315+
if (points[i].y + (maxStep - 1) * dy > col || points[i].y + (maxStep - 1) * dy < 1)
316+
{
317+
continue;
318+
}
319+
int steps = searchPath(points[j], dx, dy);
320+
if (steps > maxStep)
321+
{
322+
maxStep = steps;
323+
}
324+
}
325+
}
326+
maxStep = maxStep == 2 ? 0 : maxStep;
327+
cout << maxStep << endl;
328+
return 0;
329+
}
330+
```
331+

0 commit comments

Comments
 (0)