forked from sukhoeing/aoapc-bac2nd-keys
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UVa177.cc
118 lines (105 loc) · 3.22 KB
/
UVa177.cc
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
// Paper Folding, UVa177
// 陈锋
#include <cassert>
#include <algorithm>
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
#define _for(i,a,b) for( int i=(a); i<(b); ++i)
using namespace std;
struct Point {
int x, y;
Point(int x=0, int y=0):x(x),y(y) {}
};
typedef Point Vector;
Vector operator+ (const Vector& A, const Vector& B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator- (const Point& A, const Point& B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator* (const Vector& A, int p) { return Vector(A.x*p, A.y*p); }
bool operator== (const Point& a, const Point &b) { return a.x == b.x && a.y == b.y; }
bool operator!= (const Point& a, const Point &b) { return !(a==b); }
bool operator< (const Point& p1, const Point& p2) { return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y); }
ostream& operator<<(ostream& os, const Point& p) {
return os<<p.x<<','<<p.y;
}
// p围绕r顺时针旋转90度,返回旋转后的点
Point rotate(const Point& p, const Point& r) {
Vector pv = p - r;
Point ans = r + Vector(pv.y, -pv.x);
return ans;
}
const int MAXN = 13;
struct Line {
Point start, end;
bool vertical;
// 围绕r顺时针旋转90度
Line rotate(const Point& r) {
Line ret;
ret.start = ::rotate(start, r);
ret.end = ::rotate(end, r);
return ret;
}
// 规整,保证start在end的左边或者上边
void normalize() {
assert(start != end);
assert(start.x == end.x || start.y == end.y);
vertical = (start.x == end.x);
if(vertical) {
if(start.y > end.y) swap(start.y, end.y);
} else {
if(start.x > end.x) swap(start.x, end.x);
}
}
};
int n, LineCnt;
vector<Line> lines;
int main()
{
lines.reserve(1<<MAXN);
while(cin>>n&&n) {
Line l;
l.end = Point(1, 0);
l.vertical = false;
lines.clear();
lines.push_back(l);
int maxY = l.start.y, minY = l.start.y,
minX = l.start.x, maxX = l.end.x;
Point s = l.start, rot = l.end;
_for(i, 0, n) {
int sz = lines.size();
_for(j, 0, sz) {
Line nl = lines[j].rotate(rot);
nl.normalize();
lines.push_back(nl);
}
rot = rotate(s, rot);
}
map<Point, char> pc;
for(auto& l : lines) {
Point& lp = l.start;
lp.x *= 2;
if(l.vertical) lp.x--;
minX = min(lp.x, minX);
maxX = max(lp.x, maxX);
minY = min(lp.y, minY);
maxY = max(lp.y, maxY);
pc[lp] = l.vertical ? '|' : '_';
}
// cout<<"minX = "<<minX<<endl;
string buf;
for(int y = maxY; y >= minY; y--) {
buf.clear();
for(int x = minX; x <= maxX; x++) {
Point p(x,y);
if(pc.count(p)) buf += pc[p];
else buf += ' ';
}
while(*(buf.rbegin()) == ' ') buf.erase(buf.size()-1);
cout<<buf<<endl;
}
cout<<"^"<<endl;
}
return 0;
}
// 13700866 177 Paper Folding Accepted C++ 0.026 2014-05-31 14:30:34