比賽連接:Herenode
本場 3道簽到題可還行,2333數組
題意很簡單就不翻譯了學習
手寫下 \(n = 1\) 的各個狀況,而後拓展到 \(n = 2,3,4\) 就清晰瞭解法,ui
只要 \(n,m\) 存在一個偶數,先手必勝spa
簡單來講當一個圖上有n個點和n條邊的時候,必定成環,感受這題數據能夠再大一點。.net
int main() { cin.tie(nullptr)->sync_with_stdio(false); int n, m; cin >> n >> m; cout << (n % 2 == 0 || m % 2 == 0 ? "YES" : "NO"); }
細節題,注意區分各類狀況翻譯
int main() { cin.tie(nullptr)->sync_with_stdio(false); int _; for (cin >> _; _--;) { int a1, b1, a2, b2; cin >> a1 >> b1 >> a2 >> b2; if (a1 > b1)swap(a1, b1); if (a2 > b2)swap(a2, b2); if (a1 == a2 && b1 == b2) {cout << "tie" << endl; continue;} if (a1 == 2 && b1 == 8 && !(a2 == 2 && b2 == 8)) {cout << "first" << endl; continue;} if (!(a1 == 2 && b1 == 8) && a2 == 2 && b2 == 8) {cout << "second" << endl; continue;} if (a1 == b1 && a2 == b2) {cout << "tie" << endl; continue;} if (a1 == b1 && a2 != b2) {cout << "first" << endl; continue;} if (a1 != b1 && a2 == b2) {cout << "second" << endl; continue;} int t1 = (a1 + b1) % 10, t2 = (a2 + b2) % 10; if (t1 > t2) {cout << "first" << endl; continue;} if (t1 < t2) {cout << "second" << endl; continue;} if (b1 > b2) {cout << "first" << endl; continue;} if (b1 < b2) {cout << "second" << endl; continue;} cout << "tie" << endl; } }
淦,又是一道數學題。code補題的時候發現比杭電第一場的簡單點blog
題意就不寫了ci
符合條件的顯然是兩個球的相交。設兩點分別爲 \((x_1,y_1,z_1),(x_2,y_2,z_2)\) ,那麼根據題意,\((x,y,z)\) 須要知足:
那麼球心座標爲:\((\frac{k^2x_2-x_1}{k^2-1},\frac{k^2y_2-y_1}{k^2-1},\frac{k^2z_2-z_1}{k^2-1})\)
半徑爲:\(\sqrt{\frac{x_1^2+y_1^2+z_1^2 - k^2x_2^2 - k^2y_2^2-k^2z_2^2}{k^2-1}+(\frac{x_1-k^2x_2}{k_2-1})^2+(\frac{y_1-k^2y_2}{k_2-1})^2+(\frac{z_1-k^2z_2}{k_2-1})^2}\)
【AC Code】碼 Latex 好累呀...
const double pi = acos(-1); double x[5], y[5], z[5]; double k1, k2; void solve(double x1, double y1, double z1, double r1, double x2, double y2, double z2, double r2) { double ans = 0; double dis = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2)); if (dis >= r1 + r2) ans = 0; else if (dis + r1 <= r2) ans = (4.00 / 3.00) * pi * r1 * r1 * r1; else if (dis + r2 <= r1) ans = (4.00 / 3.00) * pi * r2 * r2 * r2; else { double cal = (r1 * r1 + dis * dis - r2 * r2) / (2.00 * dis * r1); double h = r1 * (1 - cal); ans += (1.00 / 3.00) * pi * (3.00 * r1 - h) * h * h; cal = (r2 * r2 + dis * dis - r1 * r1) / (2.00 * dis * r2); h = r2 * (1.00 - cal); ans += (1.00 / 3.00) * pi * (3.00 * r2 - h) * h * h; } printf("%.3f\n", ans); } int read() { int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar();} return x * f; } int main() { int T = read(); while (T--) { for (int i = 0; i < 4; i++) x[i] = read(), y[i] = read(), z[i] = read(); k1 = read(), k2 = read(); double c1x, c1y, c1z, c1r, t; c1x = (k1 * k1 * x[1] - x[0]) / (k1 * k1 - 1); c1y = (k1 * k1 * y[1] - y[0]) / (k1 * k1 - 1); c1z = (k1 * k1 * z[1] - z[0]) / (k1 * k1 - 1); t = k1 * k1 * ((x[1] * x[1]) + (y[1] * y[1]) + (z[1] * z[1])) - x[0] * x[0] - y[0] * y[0] - z[0] * z[0]; t /= (k1 * k1 - 1); c1r = sqrt(c1x * c1x + c1y * c1y + c1z * c1z - t); double c2x, c2y, c2z, c2r; c2x = (k2 * k2 * x[3] - x[2]) / (k2 * k2 - 1); c2y = (k2 * k2 * y[3] - y[2]) / (k2 * k2 - 1); c2z = (k2 * k2 * z[3] - z[2]) / (k2 * k2 - 1); t = k2 * k2 * ((x[3] * x[3]) + (y[3] * y[3]) + (z[3] * z[3])) - x[2] * x[2] - y[2] * y[2] - z[2] * z[2]; t /= (k2 * k2 - 1); c2r = sqrt(c2x * c2x + c2y * c2y + c2z * c2z - t); solve(c1x, c1y, c1z, c1r, c2x, c2y, c2z, c2r); } return 0; }
不過本題彷佛有其餘數學寫法,歡迎補充
題意大意:
兩個 \(20 \times 20\) 的地圖,兩個玩家操做的角色分別須要從 \((20,20),(20,1)\) 走到 \((1,20),(1,1)\),同時需在地圖上用 A
記錄最短路徑並輸出
裸的 BFS 保存路徑的搜索?
我這裏把兩個圖一塊兒搜了,若是怕寫亂也可拆開來跑兩次BFS
【AC Code】注意細節
const int N = 30, inf = 0x3f3f3f3f; char e1[N][N], e2[N][N], path[N * N * 2], dir[] = {'D', 'L', 'R', 'U'}; int cnt; struct node { int x1, y1, x2, y2;// 當前座標 } pre[N][N][N][N]; int d[N][N][N][N], p[N][N][N][N]; int Dir[4][4] = {1, 0, 1, 0, 0, -1, 0, 1, 0, 1, 0, -1, -1, 0, -1, 0}; void BFS() { queue<node>q; memset(d, inf, sizeof(d)); d[20][20][20][1] = 0; q.push(node{20, 20, 20, 1}); while (!q.empty()) { node tmp = q.front(); q.pop(); int x1 = tmp.x1, y1 = tmp.y1, x2 = tmp.x2, y2 = tmp.y2; int dis = d[x1][y1][x2][y2]; for (int i = 0; i < 4; ++i) { int u1 = x1 + Dir[i][0], v1 = y1 + Dir[i][1]; int u2 = x2 + Dir[i][2], v2 = y2 + Dir[i][3]; if (e1[u1][v1] != '.')u1 -= Dir[i][0], v1 -= Dir[i][1]; if (e2[u2][v2] != '.')u2 -= Dir[i][2], v2 -= Dir[i][3]; if (dis + 1 < d[u1][v1][u2][v2]) { d[u1][v1][u2][v2] = dis + 1; pre[u1][v1][u2][v2] = node{x1, y1, x2, y2}; p[u1][v1][u2][v2] = i; q.push(node{u1, v1, u2, v2}); } } } } void solve(node u) { int x1 = u.x1, y1 = u.y1, x2 = u.x2, y2 = u.y2; e1[x1][y1] = e2[x2][y2] = 'A'; if (x1 == 20 and y1 == 20 and x2 == 20 and y2 == 1)return ; solve(pre[x1][y1][x2][y2]); path[cnt++] = dir[p[x1][y1][x2][y2]]; } int main() { cin.tie(nullptr)->sync_with_stdio(false); for (int i = 1; i <= 20; ++i)scanf("%s %s", e1[i] + 1, e2[i] + 1); BFS(); solve(node{1, 20, 1, 1}); cout << cnt << "\n" << path << "\n"; for (int i = 1; i <= 20; ++i)printf("%s %s\n", e1[i] + 1, e2[i] + 1); }
比賽時,學長指出K題是構造一個前 \(p_i\) 個數中非降子序列長度爲 \(a_i\) 的數組
但細節上沒處理好。
這道題實際上可直接模擬,先填好給出的 \(k\) 個位置,而後補充空位 if (!a[i])a[i] = a[i - 1] + 1;
但填充過程發現 if (a[i] > a[i - 1] + 1)
則能夠直接輸出 -1
了
剩下就是直接模擬題意了
另外 K神 有一個樹狀數組的解法,值得學習一下
const int N = 1e6 + 10; int a[N]; int main() { cin.tie(nullptr)->sync_with_stdio(false); int n, k; cin >> n >> k; while (k--) { int x, y; cin >> x >> y; a[x] = y; } for (int i = 1; i <= n; ++i) { if (!a[i])a[i] = a[i - 1] + 1; else if (a[i] > a[i - 1] + 1) { cout << -1; return 0; } } stack<int>stk; int t = 1; for (int i = n; i > 0; --i) { while (stk.size() < a[i])stk.push(t++); a[i] = stk.top(); stk.pop(); } for (int i = 1; i <= n; ++i) cout << a[i] << " \n"[i == n]; }