Codeforces Round #504 E. Down or Right
阿新 • • 發佈:2018-08-19
std puts name font vector oid ask can for
能到左邊的點就向左走,走到對角線,這樣構造能保證最終在對角線的點一定重合。
因為優先向下走能保證\(D_1-R_1\)最大,那後面一半的\(R_2-D_2=(n-1-R_1)-(n-1-D_1)=D_1-R_1\)最大,而優先向左走正是保證\(R_2-D_2\)最大,因此對角線的點一定重合。
Codeforces Round #504 E. Down or Right
題目描述:交互題。 有一個\(n \times n\)的方陣,有一些格子是障礙,從\((1, 1)\)出發,只能向右向下走,能走到\((n, n)\),你有\(4n\)次詢問,每次詢問\((r_1, c_1)\)能否走到\((r_2, c_2)\),但這兩個點的曼哈頓距離要大於\(n-1\),最後輸出一條從\((1, 1)\)到\((n, n)\)的路徑。
solution
從\((1, 1)\)出發,優先向下走,向下走能到\((n, n)\)就向下走,走到對角線。然後從\((n, n)\)出發,優先向左走,\((1, 1)\)
因為優先向下走能保證\(D_1-R_1\)最大,那後面一半的\(R_2-D_2=(n-1-R_1)-(n-1-D_1)=D_1-R_1\)最大,而優先向左走正是保證\(R_2-D_2\)最大,因此對角線的點一定重合。
時間復雜度:\(O(2n)\)
#include <bits/stdc++.h> using namespace std; int n; vector<char> ans; char st[10]; bool ask(int r1, int c1, int r2, int c2) { printf("? %d %d %d %d\n", r1, c1, r2, c2); fflush(stdout); scanf("%s", st); return st[0]==‘Y‘; } void solve() { scanf("%d", &n); int x=1, y=1; for (int i=1; i<=n-1; ++i) if (ask(x+1, y, n, n)) x++, ans.push_back(‘D‘); else y++, ans.push_back(‘R‘); x=n, y=n; for (int i=1; i<=n-1; ++i) if (ask(1, 1, x, y-1)) y--, ans.push_back(‘R‘); else x--, ans.push_back(‘D‘); printf("! "); for (int i=0; i<n-1; ++i) putchar(ans[i]); for (int i=n*2-2-1; i>=n-1; --i) putchar(ans[i]); puts(""); fflush(stdout); } int main() { solve(); return 0; }
Codeforces Round #504 E. Down or Right