Codeforces Round #261 (Div. 2),
Codeforces Round #261 (Div. 2)
題目連結
A:給定兩點找正方形其他兩點。
分在一條線和對角線的情況判斷即可
B:一個序列選出最大和最小的數字,問差值很有幾種選法。
有不同數位情況就是兩數個數相乘,只有一個數字就是C2n
C:n個學生,k輛車,d天,要求學生兩兩之間不能在同一輛車一起d天,問怎麼一個安排的方案
對於每個學生而言,在d天的坐車情況,只要不和其他人重複即可,這樣進行dfs構造序列,如果能構造出n個不同序列,就是可以的,如果不能就輸出-1
D:求f(1, i, ai) > f(j, n, aj)的個數
用樹狀數組,就可以搞了,類似求逆序數那樣先把數字離散化掉,然後從前往後搞一次,記錄下來,再從後往前搞一次即可
E:一個有向圖,找出一條最長路徑,滿足路上的長度是一直遞增的
dp,dp[i]表示i結點的情況,然後先把邊按權值排序,這樣的話就保證從小到大,這樣遍曆到每條邊,對於當前邊而言它都是最大邊,肯定可以加進去,然後進行dp即可,注意對於一個權值的邊可能有多條,這樣的話如果直接狀態轉移,就轉移到當前長度相同的邊,其實這裡只需要再多開一個數組記錄下來,每次狀態轉移就在這個數組基礎上狀態轉移,轉移完在賦值過去即可
代碼:
A:
#include <cstdio>#include <cstring>#include <cstdlib>int x1, y1, x2, y2;bool judge() { if (y1 == y2) { int len = abs(x2 - x1); printf("%d %d %d %d\n", x1, y1 + len, x2, y2 + len); } else if (x1 == x2) { int len = abs(y1 - y2); printf("%d %d %d %d\n", x1 + len, y1, x2 + len, y2); } else { if (abs(x1 - x2) != abs(y1 - y2)) return false; printf("%d %d %d %d\n", x1, y2, x2, y1); } return true;}int main() { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); if (!judge()) printf("-1\n"); return 0;}
B:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int INF = 0x3f3f3f3f;const int N = 200005;int n, b[N], Max = 0, Min = INF;int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &b[i]); Max = max(Max, b[i]); Min = min(Min, b[i]); } int cnt1 = 0, cnt2 = 0; for (int i = 0; i < n; i++) { if (Max == b[i]) cnt1++; if (Min == b[i]) cnt2++; } if (Max == Min) printf("0 %lld\n", (long long)cnt1 * (cnt1 - 1) / 2); else printf("%d %lld\n", Max - Min, (long long)cnt1 * cnt2); return 0;}
C:
#include <cstdio>#include <cstring>const int N = 1005;int n, k, d, sum = 0, ans[N][N], save[N];bool dfs(int u) {int i;if (u == d) {for (i = 0; i < d; i++)ans[sum][i] = save[i];sum++;if (sum == n) {for (i = 0; i < d; i++) {for (int j = 0; j < n - 1; j++)printf("%d ", ans[j][i]);printf("%d\n", ans[n - 1][i]);}return true;}return false;}for (i = 1; i <= k; i++) {save[u] = i;if (dfs(u + 1)) return true;}return false;}int main() {scanf("%d%d%d", &n, &k, &d);if (!dfs(0)) printf("-1\n");return 0;}
D:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int lowbit(int x) { return (x&(-x));}const int N = 1000005;int n, bit[N], bit2[N], save[N], bit3[N];struct Num { int a, b, id;} nu[N];void add(int *bit, int x, int v) { while (x < N) { bit[x] += v; x += lowbit(x); }}int get(int *bit, int x) { int ans = 0; while (x) { ans += bit[x]; x -= lowbit(x); } return ans;}bool cmp1(Num a, Num b) {return a.a < b.a;}bool cmp2(Num a, Num b) {return a.id < b.id;}int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &nu[i].a); nu[i].id = i; } sort(nu, nu + n, cmp1); int cnt = 1; nu[0].b = 1; for (int i = 1; i < n; i++) { if (nu[i].a != nu[i - 1].a) cnt++; nu[i].b = cnt; } sort(nu, nu + n, cmp2); for (int i = 0; i < n; i++) { add(bit, nu[i].b, 1); add(bit2, get(bit, nu[i].b) - get(bit, nu[i].b - 1), 1); } long long ans = 0; for (int i = n - 1; i >= 0; i--) { add(bit2, get(bit, nu[i].b) - get(bit, nu[i].b - 1), -1); add(bit, nu[i].b, -1); add(bit3, nu[i].b, 1); int tmp = get(bit3, nu[i].b) - get(bit3, nu[i].b - 1); ans += get(bit2, n) - get(bit2, tmp); } printf("%lld\n", ans); //system("pause"); return 0;}
E:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 300005;int n, m, dp[2][N];struct Edge { int u, v, w;} e[N];bool cmp(Edge a, Edge b) { return a.w < b.w;}int main() { scanf("%d%d", &n, &m); for (int i = 0; i < m; i++) scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w); sort(e, e + m, cmp); for (int i = 0; i < m; i++) { int j; for (j = i; e[i].w == e[j].w; j++) dp[1][e[j].v] = max(dp[1][e[j].v], dp[0][e[j].u] + 1); for (j = i; e[i].w == e[j].w; j++) dp[0][e[j].v] = dp[1][e[j].v]; i = j - 1; } int ans = 0; for (int i = 1; i <= n; i++) ans = max(ans, dp[0][i]); printf("%d\n", ans); //system("pause"); return 0;}