-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproject2.cpp
178 lines (155 loc) · 3.48 KB
/
project2.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
175
176
177
178
#include <iostream>
#include <fstream>
using namespace std;
int R, C, B;
char floor_map[1000+5][1000+5];
//0-->floor need to clean
//1-->obstacle
//2-->have cleaned:)
fstream tmpFile;
using Point = struct point{
int x, y;
};
bool operator == (Point A, Point B){
return A.x == B.x && A.y == B.y;
}
bool operator != (Point A, Point B){
return A.x != B.x || A.y != B.y;
}
Point RP;
int dirty;
bool all_clean();
void sum_dirty();
int step_map[1000+5][1000+5];
void cal_step_map(Point start);
Point find_farthest();
int A2B(Point A, Point B);
void dfs_back(Point cur, Point A, Point B);
void dfs_to(Point cur, Point A);
int main(){
//read map
ifstream inFile("floor.data");
if(!inFile) cout << "fail to open floor.data \n";
char input_map[1005][1005];
inFile >> R >> C >> B;
for(int i = 0; i < R; ++i)
inFile >> input_map[i];
inFile.close();
//copy map and find R
for(int i = 0; i < R; ++i){
for(int j = 0; j < C; ++j){
floor_map[i][j] = input_map[i][j];
if(input_map[i][j] == 'R'){
RP.x = i;
RP.y = j;
}
}
}
//cal total steps
tmpFile.open("tmp.path", ios::out);
Point pos = RP;
int total_step = 0;
cal_step_map(pos);
sum_dirty();
while(!all_clean()){
Point target = find_farthest();
total_step += 2*A2B(pos, target);
}
tmpFile.close();
//copy path from tmp.path to final.path
fstream outFile;
outFile.open("final.path", ios::out);
outFile << total_step << '\n';
outFile << RP.x << ' ' << RP.y << '\n';
ifstream tmpinFile("tmp.path");
if(!tmpinFile) cout << "fail to open tmp.path \n";
int x, y;
for(int i = 0; i < total_step; ++i){
tmpinFile >> x >> y;
outFile << x << ' ' << y << '\n';
}
tmpinFile.close();
outFile.close();
return 0;
}
bool all_clean(){
return dirty == 0;
}
void sum_dirty(){
dirty = 0;
for(int i = 0; i < R; ++i)
for(int j = 0; j < C; ++j)
if(floor_map[i][j] == '0') dirty++;
}
int dx[4] = {0, 0, -1, 1},
dy[4] = {-1, 1, 0, 0};
Point queue[1000000];
Point pre_step[1005][1005];
void cal_step_map(Point start){
for(int i = 0; i < R; ++i)
for(int j = 0; j < C; ++j)
step_map[i][j] = 0;
int N = 1000000;
int front = -1, rear = -1;
queue[++rear] = start;
step_map[start.x][start.y] = 0;
while(front != rear){
front = (front + 1) % N;
Point ptr = queue[front];
for(int i = 0; i < 4; ++i){
Point tmp;
tmp.x = ptr.x + dx[i];
tmp.y = ptr.y + dy[i];
if(tmp == RP ||tmp.x >= R || tmp.x < 0 || tmp.y >= C || tmp.y < 0 ||
floor_map[tmp.x][tmp.y] == '1' || step_map[tmp.x][tmp.y] != 0) continue;
pre_step[tmp.x][tmp.y] = ptr;
step_map[tmp.x][tmp.y] = step_map[ptr.x][ptr.y] + 1;
rear = (rear + 1) % N;
queue[rear] = tmp;
}
}
}
Point find_farthest(){
int max_dis = -1;
Point ans;
ans.x = 0;
ans.y = 0;
for(int i = 0; i < R; ++i){
for(int j = 0; j < C; ++j){
if(floor_map[i][j] == '0' && step_map[i][j] > max_dis){
max_dis = step_map[i][j];
ans.x = i;
ans.y = j;
}
}
}
return ans;
}
int A2B(Point A, Point B){
int step = 0;
int disAB = step_map[B.x][B.y];
dfs_to(B, A);
dfs_back(B, A, B);
return disAB;
}
void dfs_to(Point cur, Point A){
if(cur == A){
return;
}else{
dfs_to(pre_step[cur.x][cur.y], A);
if(floor_map[cur.x][cur.y] == '0'){
floor_map[cur.x][cur.y] = '2';
dirty--;
}
tmpFile << cur.x << ' ' << cur.y << "\n";
}
}
void dfs_back(Point cur, Point A, Point B){
if(cur == A){
tmpFile << cur.x << ' ' << cur.y << "\n";
return;
}else{
if(cur != B) tmpFile << cur.x << ' ' << cur.y << "\n";
dfs_back(pre_step[cur.x][cur.y], A, B);
}
}