这道题一上手就知道怎么做了= =
直接求出原光路和从目标点出发的光路,求这些光路的交点就行了
然后用树状数组+扫描线或函数式线段树就能过了= =
大量的离散+模拟+二分什么的特别恶心,考试的时候是想到了不过被代码难度吓到了根本不想写QAQ
这时官方的代码就显现出了c++的STL的强大功能了
离散sort+unique+resize+lower_bound直接秒杀,模拟也是lower_bound+讨论直接秒杀
不得不让我这种一直还在手打二分的情何以堪啊QAQ
比较一下吧 官方3K,一同学(c++)6K,两初中的(Pascal)9K和20K (不得不感叹初中生已经突破天际了啊= =,不过那个20K的6个快排也是醉了= =)
CODE:(强烈建议学习其离散化的写法)
#include <iostream> #include <vector> #include <map> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; #define MAXN (1 << 17) #define MAXVAL 1000000000 int dx[] = {0, 1, 0, -1}; int dy[] = {1, 0, -1, 0}; map<int, vector<pair<int, char> > > objx; map<int, vector<pair<int, char> > > objy; pair<pair<int, int>, char> getnext(int x, int y, int dir) { bool vmove = dir % 2 == 0; int a = vmove ? x : y; int b = vmove ? y : x; int db = vmove ? dy[dir] : dx[dir]; vector<pair<int, char> >& objs = (vmove ? objx : objy)[a]; int id = lower_bound(objs.begin(), objs.end(), make_pair(b, (char)0)) - objs.begin(); id += db; char ch = '?'; if(id < 0) { b = -(MAXVAL + 1); } else if(id == objs.size()) { b = MAXVAL + 1; } else { b = objs[id].first; ch = objs[id].second; } return make_pair(vmove ? make_pair(a, b) : make_pair(b, a), ch); } vector<pair<int, int> > getpath(int x, int y, int dir) { pair<int, int> pos(x, y); vector<pair<int, int> > path(1, pos); for(;;) { pair<pair<int, int>, char> res = getnext(pos.first, pos.second, dir); pos = res.first; path.push_back(pos); if(res.second == '/') { dir = (dir + (dir % 2 != 0 ? 3 : 1)) % 4; } else if(res.second == '\') { dir = (dir + (dir % 2 == 0 ? 3 : 1)) % 4; } else { break; } } return path; } vector<pair<int, pair<int, int> > > getverts(vector<pair<int, int> >& path) { vector<pair<int, pair<int, int> > > ret; for(int i = 0; i + 1 < path.size(); i++) { if(path[i].first == path[i + 1].first) { ret.push_back(make_pair(path[i].first, make_pair(path[i].second, path[i + 1].second))); if(ret.back().second.second < ret.back().second.first) { swap(ret.back().second.first, ret.back().second.second); } } } return ret; } vector<pair<int, pair<int, int> > > gethorz(vector<pair<int, int> >& path) { vector<pair<int, pair<int, int> > > ret; for(int i = 0; i + 1 < path.size(); i++) { if(path[i].second == path[i + 1].second) { ret.push_back(make_pair(path[i].second, make_pair(path[i].first, path[i + 1].first))); if(ret.back().second.second < ret.back().second.first) { swap(ret.back().second.first, ret.back().second.second); } } } return ret; } int BT[MAXN]; /* Logically executes array[x] += v. */ void bit_add(int x, int v) { for(int i = x | MAXN; i < (MAXN << 1); i += i & -i) { BT[i ^ MAXN] += v; } } /* Returns the sum of array[i] for 0 <= i < x */ int bit_get(int x) { int ret = 0; for(int i = x - 1; x != 0; i &= i - 1) { ret += BT[i]; if(!i) break; } return ret; } int countints(vector<pair<int, pair<int, int> > > vs, vector<pair<int, pair<int, int> > > hs) { /* Start with a coordinate compression of y values. */ vector<int> ys; for(int i = 0; i < vs.size(); i++) { ys.push_back(vs[i].second.first); ys.push_back(vs[i].second.second); } for(int i = 0; i < hs.size(); i++) { ys.push_back(hs[i].first); } sort(ys.begin(), ys.end()); ys.resize(unique(ys.begin(), ys.end()) - ys.begin()); for(int i = 0; i < vs.size(); i++) { vs[i].second.first = lower_bound(ys.begin(), ys.end(), vs[i].second.first) - ys.begin(); vs[i].second.second = lower_bound(ys.begin(), ys.end(), vs[i].second.second) - ys.begin(); } for(int i = 0; i < hs.size(); i++) { hs[i].first = lower_bound(ys.begin(), ys.end(), hs[i].first) - ys.begin(); } /* Sort vertical intervals by x, create event list. */ sort(vs.begin(), vs.end()); vector<pair<pair<int, int>, int> > events; for(int i = 0; i < hs.size(); i++) { events.push_back(make_pair(make_pair(hs[i].second.first, hs[i].first), 1)); events.push_back(make_pair(make_pair(hs[i].second.second, hs[i].first), -1)); } sort(events.begin(), events.end()); /* Finally, count the intersections using a Fenwick tree. */ int result = 0; memset(BT, 0, sizeof(BT)); for(int i = 0, j = 0; i < events.size(); i++) { int x = events[i].first.first; for(; j < vs.size() && vs[j].first < x; j++) { result += bit_get(vs[j].second.second) - bit_get(vs[j].second.first + 1); } bit_add(events[i].first.second, events[i].second); } return result; } int main() { freopen("optics.in", "r", stdin); freopen("optics.out", "w", stdout); int N, bx, by; cin >> N >> bx >> by; objx[0].push_back(make_pair(0, 'S')); objy[0].push_back(make_pair(0, 'S')); objx[bx].push_back(make_pair(by, 'B')); objy[by].push_back(make_pair(bx, 'B')); for(int i = 0; i < N; i++) { int x, y; string mr; cin >> x >> y >> mr; objx[x].push_back(make_pair(y, mr[0])); objy[y].push_back(make_pair(x, mr[0])); } for(map<int, vector<pair<int, char> > >::iterator it = objx.begin(); it != objx.end(); ++it) { sort(it->second.begin(), it->second.end()); } for(map<int, vector<pair<int, char> > >::iterator it = objy.begin(); it != objy.end(); ++it) { sort(it->second.begin(), it->second.end()); } int result = 0; vector<pair<int, int> > plaser = getpath(0, 0, 0); for(int i = 0; i < 4; i++) { vector<pair<int, int> > pbarn = getpath(bx, by, i); int res = countints(getverts(plaser), gethorz(pbarn)) + countints(getverts(pbarn), gethorz(plaser)); if(pbarn[0] == pbarn.back()) { result += res; } else { result += 2 * res; } } cout << result / 2 << endl; return 0; }