{"pageProps":{"post":{"id":3,"title":"今日头条笔试解题报告(10.17)","content":"之前随便投了一下今日头条竟然过了,虽然不是很想去,但是已经给了我笔试邀约好歹也就做一下,锻炼锻炼脑子,说句实话还是挺喜欢头条的题目的,做起来很有以前 ACM 刷题的感觉,不像其他公司总感觉\"工程化\"比较多。\n\n## 推箱子\n\n第一题比较简单,表面上无从下手但是仔细想想应该能想出来的,本质上跟走迷宫问题本质上是一致的,只不过在这题中状态既要保存人的位置也要保存箱子的位置。暴力搜索能够,AC 代码:\n\n\n\n```C++\n#include\n#include\n#include\n#include\n#include\nusing namespace std;\nchar mp[55][55];\nbool used[55][55][55][55];\nint n, m;\nstruct Point {\n\tint x, y;\n}you, st, ed;\n\nstruct State {\n\tint x, y, xx, yy, step;\n\tState() { step = 0; };\n\tState(int x, int y, int xx, int yy,int step) {\n\t\tthis->x = x;\n\t\tthis->y = y;\n\t\tthis->xx = xx;\n\t\tthis->yy = yy;\n\t\tthis->step = step;\n\t}\n\tState(Point a, Point b) {\n\t\tx = a.x;\n\t\ty = a.y;\n\t\txx = b.x;\n\t\tyy = b.y;\n\t\tstep = 0;\n\t}\n};\n\nint dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };\nbool valid(int x, int y) {\n\tif (x<1 || x>n ) return false;\n\tif (y<1 || y>m ) return false;\n\tif (mp[x][y] == '#') return false;\n\treturn true;\n}\n\nint bfs() {\n\tqueueQ;\n\tmemset(used, 0, sizeof(used));\n\tState start(you,st);\n\tQ.push(start);\n\tused[start.x][start.y][start.xx][start.yy] = 1;\n\twhile (!Q.empty()) {\n\t\tState cur = Q.front();\n\t\tif (cur.xx == ed.x && cur.yy == ed.y) return cur.step;\n\t\tfor (int i = 0; i < 4; i++) {\n\t\t\tint x = cur.x + dir[i][0];\n\t\t\tint y = cur.y + dir[i][1];\n\t\t\tint xx = cur.xx;\n\t\t\tint yy = cur.yy;\n\t\t\tif (!valid(x, y))continue;\n\t\t\tif (x == cur.xx && y == cur.yy) {\n\t\t\t\txx = cur.xx + dir[i][0];\n\t\t\t\tyy = cur.yy + dir[i][1];\n\t\t\t}\n\t\t\tif (!valid(xx, yy)) continue;\n\n\t\t\tif (xx == ed.x && yy == ed.y) {\n\t\t\t\treturn cur.step + 1;\n\t\t\t}\n\t\t\tif (!used[x][y][xx][yy]) {\n\t\t\t\tused[x][y][xx][yy] = 1;\n\t\t\t\tQ.push(State(x, y, xx, yy,cur.step + 1));\n\t\t\t}\n\t\t}\n\t\tQ.pop();\n\t}\n\treturn -1;\n}\nint main() {\n\twhile (cin>>n>>m) {\n\t\tfor (int i = 1; i <= n; i++) {\n\t\t\tfor (int j = 1; j <= m; j++) {\n\t\t\t\tcin >> mp[i][j];\n\t\t\t\tif (mp[i][j] == 'S') {\n\t\t\t\t\tyou.x = i;\n\t\t\t\t\tyou.y = j;\n\t\t\t\t}\n\t\t\t\tif (mp[i][j] == '0') {\n\t\t\t\t\tst.x = i;\n\t\t\t\t\tst.y = j;\n\t\t\t\t}\n\t\t\t\tif (mp[i][j] == 'E') {\n\t\t\t\t\ted.x = i;\n\t\t\t\t\ted.y = j;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcout << bfs() << endl;\n\t}\n}\n/*\n3 6\n.S#..E\n.#.0..\n......\n*/\n```\n\n## 房间重排\n\n设有 n 个房间,将第 i 个房间的人取出来,依次重新安排到 i+1,i+2,...1,2,3 的房间,不断循环。给你最终各房间人数和最后安排的房间,求最开始的各个房间中人数。\n\n这题有多解,special judge。基本思路就是找到一个包含人数最少的房间,从这个房间开始逆推还原。\n\n```C++\n#include\n#include\n#include\n#include\nusing namespace std;\nint n, m;\nlong long a[111111], b[111111];\nvectorvt;\n\nbool check(int mIndex) {\n\tfor (int i = 0; i < n; i++) {\n\t\tif (i == mIndex) b[i] = n * a[i];\n\t\telse b[i] = a[i] - a[mIndex];\n\t}\n\tfor (int i = mIndex; i != m; i = (i + 1) % n) {\n\t\tb[i]--;\n\t\tb[mIndex]++;\n\t\tif (b[i] < 0) return false;\n\t}\n\treturn true;\n}\nint main() {\n\twhile (~scanf(\"%d%d\", &n, &m)) {\n\t\tlong long mVal = -1;\n\t\tvt.clear();\n\t\tm--;\n\t\tfor (int i = 0; i < n; i++) {\n\t\t\tcin >> a[i];\n\t\t\tif (mVal == -1 || mVal >= a[i]) {\n\t\t\t\tif (mVal > a[i])vt.clear();\n\t\t\t\tmVal = a[i];\n\t\t\t\tvt.push_back(i);\n\t\t\t}\n\t\t}\n\t\tfor (int i = 0; i < (int)vt.size(); i++) {\n\t\t\tint mIndex = vt[i];\n\t\t\tif (check(mIndex))break;\n\t\t}\n\t\tfor (int i = 0; i < n; i++) {\n\t\t\tprintf(\"%lld%c\", b[i], i == n - 1 ? '\\n' : ' ');\n\t\t}\n\t}\n}\n/*\n3 1\n6 5 1\n*/\n```","slug":"toutiao-test","draft":false,"createdAt":"2017-10-18T01:26:50+00:00","updatedAt":"2020-07-28T05:18:21+00:00","author":{"id":1,"name":"admin","email":"unknown@unknown.com","bio":"","githubId":"22012452","__typename":"User"},"categories":[{"id":3,"slug":"acm","name":"ACM","__typename":"Category"}],"tags":[{"id":5,"slug":"%E6%8B%9B%E8%81%98","name":"招聘","__typename":"Tag"},{"id":6,"slug":"%E7%BD%91%E6%98%93","name":"网易","__typename":"Tag"},{"id":7,"slug":"lcs","name":"LCS","__typename":"Tag"},{"id":8,"slug":"%E6%9A%B4%E5%8A%9B","name":"暴力","__typename":"Tag"}],"__typename":"Post"},"apolloState":{"Post:3":{"id":3,"title":"今日头条笔试解题报告(10.17)","content":"之前随便投了一下今日头条竟然过了,虽然不是很想去,但是已经给了我笔试邀约好歹也就做一下,锻炼锻炼脑子,说句实话还是挺喜欢头条的题目的,做起来很有以前 ACM 刷题的感觉,不像其他公司总感觉\"工程化\"比较多。\n\n## 推箱子\n\n第一题比较简单,表面上无从下手但是仔细想想应该能想出来的,本质上跟走迷宫问题本质上是一致的,只不过在这题中状态既要保存人的位置也要保存箱子的位置。暴力搜索能够,AC 代码:\n\n\n\n```C++\n#include\n#include\n#include\n#include\n#include\nusing namespace std;\nchar mp[55][55];\nbool used[55][55][55][55];\nint n, m;\nstruct Point {\n\tint x, y;\n}you, st, ed;\n\nstruct State {\n\tint x, y, xx, yy, step;\n\tState() { step = 0; };\n\tState(int x, int y, int xx, int yy,int step) {\n\t\tthis->x = x;\n\t\tthis->y = y;\n\t\tthis->xx = xx;\n\t\tthis->yy = yy;\n\t\tthis->step = step;\n\t}\n\tState(Point a, Point b) {\n\t\tx = a.x;\n\t\ty = a.y;\n\t\txx = b.x;\n\t\tyy = b.y;\n\t\tstep = 0;\n\t}\n};\n\nint dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };\nbool valid(int x, int y) {\n\tif (x<1 || x>n ) return false;\n\tif (y<1 || y>m ) return false;\n\tif (mp[x][y] == '#') return false;\n\treturn true;\n}\n\nint bfs() {\n\tqueueQ;\n\tmemset(used, 0, sizeof(used));\n\tState start(you,st);\n\tQ.push(start);\n\tused[start.x][start.y][start.xx][start.yy] = 1;\n\twhile (!Q.empty()) {\n\t\tState cur = Q.front();\n\t\tif (cur.xx == ed.x && cur.yy == ed.y) return cur.step;\n\t\tfor (int i = 0; i < 4; i++) {\n\t\t\tint x = cur.x + dir[i][0];\n\t\t\tint y = cur.y + dir[i][1];\n\t\t\tint xx = cur.xx;\n\t\t\tint yy = cur.yy;\n\t\t\tif (!valid(x, y))continue;\n\t\t\tif (x == cur.xx && y == cur.yy) {\n\t\t\t\txx = cur.xx + dir[i][0];\n\t\t\t\tyy = cur.yy + dir[i][1];\n\t\t\t}\n\t\t\tif (!valid(xx, yy)) continue;\n\n\t\t\tif (xx == ed.x && yy == ed.y) {\n\t\t\t\treturn cur.step + 1;\n\t\t\t}\n\t\t\tif (!used[x][y][xx][yy]) {\n\t\t\t\tused[x][y][xx][yy] = 1;\n\t\t\t\tQ.push(State(x, y, xx, yy,cur.step + 1));\n\t\t\t}\n\t\t}\n\t\tQ.pop();\n\t}\n\treturn -1;\n}\nint main() {\n\twhile (cin>>n>>m) {\n\t\tfor (int i = 1; i <= n; i++) {\n\t\t\tfor (int j = 1; j <= m; j++) {\n\t\t\t\tcin >> mp[i][j];\n\t\t\t\tif (mp[i][j] == 'S') {\n\t\t\t\t\tyou.x = i;\n\t\t\t\t\tyou.y = j;\n\t\t\t\t}\n\t\t\t\tif (mp[i][j] == '0') {\n\t\t\t\t\tst.x = i;\n\t\t\t\t\tst.y = j;\n\t\t\t\t}\n\t\t\t\tif (mp[i][j] == 'E') {\n\t\t\t\t\ted.x = i;\n\t\t\t\t\ted.y = j;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcout << bfs() << endl;\n\t}\n}\n/*\n3 6\n.S#..E\n.#.0..\n......\n*/\n```\n\n## 房间重排\n\n设有 n 个房间,将第 i 个房间的人取出来,依次重新安排到 i+1,i+2,...1,2,3 的房间,不断循环。给你最终各房间人数和最后安排的房间,求最开始的各个房间中人数。\n\n这题有多解,special judge。基本思路就是找到一个包含人数最少的房间,从这个房间开始逆推还原。\n\n```C++\n#include\n#include\n#include\n#include\nusing namespace std;\nint n, m;\nlong long a[111111], b[111111];\nvectorvt;\n\nbool check(int mIndex) {\n\tfor (int i = 0; i < n; i++) {\n\t\tif (i == mIndex) b[i] = n * a[i];\n\t\telse b[i] = a[i] - a[mIndex];\n\t}\n\tfor (int i = mIndex; i != m; i = (i + 1) % n) {\n\t\tb[i]--;\n\t\tb[mIndex]++;\n\t\tif (b[i] < 0) return false;\n\t}\n\treturn true;\n}\nint main() {\n\twhile (~scanf(\"%d%d\", &n, &m)) {\n\t\tlong long mVal = -1;\n\t\tvt.clear();\n\t\tm--;\n\t\tfor (int i = 0; i < n; i++) {\n\t\t\tcin >> a[i];\n\t\t\tif (mVal == -1 || mVal >= a[i]) {\n\t\t\t\tif (mVal > a[i])vt.clear();\n\t\t\t\tmVal = a[i];\n\t\t\t\tvt.push_back(i);\n\t\t\t}\n\t\t}\n\t\tfor (int i = 0; i < (int)vt.size(); i++) {\n\t\t\tint mIndex = vt[i];\n\t\t\tif (check(mIndex))break;\n\t\t}\n\t\tfor (int i = 0; i < n; i++) {\n\t\t\tprintf(\"%lld%c\", b[i], i == n - 1 ? '\\n' : ' ');\n\t\t}\n\t}\n}\n/*\n3 1\n6 5 1\n*/\n```","slug":"toutiao-test","draft":false,"createdAt":{"type":"json","json":"2017-10-18T01:26:50+00:00"},"updatedAt":{"type":"json","json":"2020-07-28T05:18:21+00:00"},"author":{"type":"id","generated":false,"id":"User:1","typename":"User"},"categories":[{"type":"id","generated":false,"id":"Category:3","typename":"Category"}],"tags":[{"type":"id","generated":false,"id":"Tag:5","typename":"Tag"},{"type":"id","generated":false,"id":"Tag:6","typename":"Tag"},{"type":"id","generated":false,"id":"Tag:7","typename":"Tag"},{"type":"id","generated":false,"id":"Tag:8","typename":"Tag"}],"__typename":"Post"},"User:1":{"id":1,"name":"admin","email":"unknown@unknown.com","bio":"","githubId":"22012452","__typename":"User"},"Category:3":{"id":3,"slug":"acm","name":"ACM","__typename":"Category"},"Tag:5":{"id":5,"slug":"%E6%8B%9B%E8%81%98","name":"招聘","__typename":"Tag"},"Tag:6":{"id":6,"slug":"%E7%BD%91%E6%98%93","name":"网易","__typename":"Tag"},"Tag:7":{"id":7,"slug":"lcs","name":"LCS","__typename":"Tag"},"Tag:8":{"id":8,"slug":"%E6%9A%B4%E5%8A%9B","name":"暴力","__typename":"Tag"},"ROOT_QUERY":{"post({\"where\":{\"slug\":\"toutiao-test\"}})":{"type":"id","generated":false,"id":"Post:3","typename":"Post"}}}},"__N_SSG":true}