信息量挺大的,短时间内要理解题意,还要想出解题方法,还要写好代码,还要考虑MLE或者TLE去优化时间、空间复杂度,还要测试是否CE,还要自己出数据验证思路对不对……反正赛时那时间我没写出来,最后几分钟草草提交,结果CE了……赛后也是写了好久,一直卡在MLE on test 5……后来才对DFS优化剪枝,用优化前后的测试数据对比判断优化是否WA了……最后才AC……🤧
structdot { int x, y; int dir; int times; dot() { } dot(int _x, int _y) : x(_x), y(_y) { dir = 0; times = 0; } dot(int _x, int _y, int d, int t) : x(_x), y(_y), dir(d), times(t) { } booloperator<(const dot d)const { if (x == d.x) return y < d.y; return x < d.x; } booloperator==(const dot d)const { return (x == d.x && y == d.y); } };
intnextDir1(int d){//往左45°产生的方向 if (d == 1) return2; if (d == 2) return4; if (d == 3) return1; if (d == 4) return6; if (d == 5) return3; if (d == 6) return4; if (d == 7) return8; if (d == 8) return6; }
intnextDir2(int d){//往右45°产生的方向 if (d == 1) return3; if (d == 2) return1; if (d == 3) return5; if (d == 4) return2; if (d == 5) return7; if (d == 6) return8; if (d == 7) return5; if (d == 8) return7; }
dot genDot(dot s, int dir){//每次走一步 产生下一个点 dot e(s.x, s.y); if (dir == 1) e.y += 1;//↑ if (dir == 4) e.x -= 1;//← if (dir == 5) e.x += 1;//→ if (dir == 8) e.y -= 1;//↓ if (dir == 2) { e.x -= 1; e.y += 1; }//↖ if (dir == 3) { e.x += 1; e.y += 1; }//↗ if (dir == 6) { e.x -= 1; e.y -= 1; }//↙ if (dir == 7) { e.x += 1; e.y -= 1; }//↘ return e; }
intmain(){ int n; cin >> n; int* step = newint[n + 10]; for (int i = 0; i < n; i++) cin >> step[i]; dot s(152, 152, 1, 0);//以防万一 起点变成(152, 152) 方向1 第0次分裂
queue<dot> q; q.push(s);
int reachCount = 0;//记录到达过多少个位置 int times = 0;//记录第几次大分裂 while (!q.empty()) { dot cur = q.front();//当前点 q.pop(); int dir = cur.dir;//当前方向 times = cur.times;//当前是第几次大分裂 if (con[cur.x][cur.y][dir - 1][times] == true)//如果这次分裂重复来过了 continue;//不用管这一次了 继续下一个循环 con[cur.x][cur.y][dir-1][times] = true;//没来过 标记true for (int i = 0; i != step[times]; i++) {//走几步 dot temp = genDot(cur, dir);//产生下一个点 cur = temp; int ca = cur.x, cb = cur.y; if (reach[ca][cb] == false) {//标记到达 reach[ca][cb] = true; reachCount++;//计数 } }
if (times < n - 1) {//还没到最后一次的大分裂 可入队 int a = cur.x, b = cur.y; dot cur1(a, b, nextDir1(dir), times + 1); dot cur2(a, b, nextDir2(dir), times + 1); //2个方向 入队 q.push(cur1); q.push(cur2); } } cout << reachCount << endl; return0; }