A - Pattern Stringnode
留坑。ios
B - Bazingac++
題意:找一個最大的i,使得前i - 1個字符串中至少不是它的子串ide
思路:暴力找,若是有一個串已經符合條件,就不用往上更新spa
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 510 5 6 int t, n; 7 int vis[N]; 8 string s[N]; 9 10 int main() 11 { 12 ios::sync_with_stdio(false); 13 int t; 14 cin >> t; 15 for(int cas = 1; cas <= t; ++cas) 16 { 17 cin >> n; 18 memset(vis, 0, sizeof vis); 19 for(int i = 1; i <= n; ++i) cin >> s[i]; 20 int ans = -1; 21 for(int i = 1; i <= n; ++i) 22 { 23 for(int j = i + 1; j <= n; ++j) 24 { 25 if(!vis[j]) 26 { 27 int tmp = s[j].find(s[i]); 28 if(tmp == -1) 29 { 30 vis[j] = 1; 31 ans = max(ans, j); 32 } 33 else break; 34 } 35 } 36 } 37 cout << "Case #" << cas << ": " << ans << endl; 38 } 39 return 0; 40 }
C - Minimum Cut-Cut翻譯
留坑。3d
D - Pagodascode
題意:剛開始集合裏有a, b 兩個數,每次能從集合中選出 x + y 或者 x - y 放進集合中,而且放過的不能放,不能放的輸遊戲xml
思路:考慮$gcd(x, y), 每次產生的新數確定是gcd(x, y)的倍數$ 因此能放的數總數只有 gcd(x, y) 的倍數的個數blog
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int gcd(int a, int b) 6 { 7 return b == 0 ? a : gcd(b, a % b); 8 } 9 10 int n, a, b; 11 12 int main() 13 { 14 int t; 15 scanf("%d", &t); 16 for(int cas = 1; cas <= t; ++cas) 17 { 18 scanf("%d %d %d", &n, &a, &b); 19 int g = gcd(a, b); 20 int tmp = n / g; 21 printf("Case #%d: ", cas); 22 puts(tmp & 1 ? "Yuwgna" : "Iaka"); 23 } 24 return 0; 25 }
E - Efficient Tree
留坑。
F - Frogs
題意:有n只青蛙,長度爲m的環,每隻青蛙固定步數往前跳,跳到一個點標記一下,求最後有多少點被標記
思路:先將m分解因子,對於每個arr[i]都和m求gcd,而後將gcd的倍數標記一次,表明須要統計一次它的倍數。最後遍歷一邊每一個因子,求出它被多用幾回或者少用幾回的和便可。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 #define ll long long 6 #define N 10010 7 8 ll gcd(ll a, ll b) 9 { 10 return b == 0 ? a : gcd(b, a % b); 11 } 12 13 int n, m; 14 int vis[N], used[N]; 15 ll arr[N]; 16 vector<int>vec; 17 18 int main() 19 { 20 int t; 21 scanf("%d", &t); 22 for(int cas = 1; cas <= t; ++cas) 23 { 24 scanf("%d %d", &n, &m); 25 memset(vis, 0, sizeof vis); 26 memset(used, 0, sizeof used); 27 vec.clear(); 28 for(int i = 1; i * i <= m; ++i) 29 { 30 if(m % i == 0) 31 { 32 vec.push_back(i); 33 if(i * i != m) vec.push_back(m / i); 34 } 35 } 36 sort(vec.begin(), vec.end()); 37 int tot = vec.size(); 38 tot--; 39 for(int i = 1; i <= n; ++i) 40 { 41 scanf("%lld", arr + i); 42 ll x = gcd(arr[i], m); 43 for(int j = 0; j < tot; ++j) 44 { 45 if(vec[j] % x == 0) vis[j] = 1; 46 } 47 } 48 ll ans = 0; 49 for(int i = 0; i < tot; ++i) 50 { 51 if(vis[i] != used[i]) 52 { 53 ll tmp = (m - 1) / vec[i]; 54 ans += tmp * (tmp + 1) / 2 * vec[i] * (vis[i] - used[i]); 55 for(int j = i + 1; j < tot; ++j) 56 { 57 if(vec[j] % vec[i] == 0) 58 { 59 used[j] += vis[i] - used[i]; 60 } 61 } 62 } 63 } 64 printf("Case #%d: %lld\n", cas, ans); 65 } 66 return 0; 67 }
G - Game of Flying Circus
題意:翻譯啊翻譯
思路:分類討論
1)在1-2相遇 即v1=v2 輸出Yes
2)在2-3相遇,利用二分計算出相遇點,算一下到4的時間,判斷
3)在3-4相遇,利用二分計算出相遇點,算一下到1的時間,判斷
4)必定No
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const double eps = 1e-8; 6 7 double T, v1, v2; 8 9 int sgn(double x) 10 { 11 if(fabs(x) < eps) return 0; 12 else return x > 0 ? 1 : -1; 13 } 14 15 int main() 16 { 17 int t; 18 scanf("%d", &t); 19 for(int cas = 1; cas <= t; ++cas) 20 { 21 scanf("%lf %lf %lf", &T, &v1, &v2); 22 printf("Case #%d: ", cas); 23 if(sgn(v1 - v2) == 0) puts("Yes"); 24 else if(sgn(2 * v1 * v1 - v2 * v2) > 0)//2-3 25 { 26 double l = 0, r = 300.0; 27 while(r - l > eps) 28 { 29 double mid = (l + r) / 2.0; 30 double dis1 = sqrt(mid * mid + 300.0 * 300.0); 31 double t1 = dis1 / v1; 32 double dis2 = mid + 300.0; 33 double t2 = dis2 / v2; 34 if(sgn(t1 - t2) > 0) 35 { 36 l = mid; 37 } 38 else 39 { 40 r = mid; 41 } 42 } 43 double x = (l + r) / 2.0; 44 double dis1 = x + 600.0; 45 double t1 = dis1 / v1; 46 double dis2 = 600.0 - x; 47 double t2 = dis2 / v2 + T; 48 puts(sgn(t1 - t2) <= 0 ? "Yes" : "No"); 49 } 50 else if(sgn(3 * v1 - v2) > 0)//3-4 51 { 52 double l = 0, r = 300.0; 53 while(r - l > eps) 54 { 55 double mid = (l + r) / 2.0; 56 double dis1 = sqrt(mid * mid + 300.0 * 300.0); 57 double t1 = dis1 / v1; 58 double dis2 = 900.0 - mid; 59 double t2 = dis2 / v2; 60 if(sgn(t1 - t2) > 0) 61 { 62 r = mid; 63 } 64 else 65 { 66 l = mid; 67 } 68 } 69 double y = (l + r) / 2.0; 70 double dis1 = sqrt((300.0 - y) * (300.0 - y) + 300.0 * 300.0) + 900.0; 71 double t1 = dis1 / v1; 72 double dis2 = y + 300.0; 73 double t2 = dis2 / v2 + T; 74 puts(sgn(t1 - t2) <= 0 ? "Yes" : "No"); 75 } 76 else puts("No"); 77 } 78 return 0; 79 }
H - Chessboard
留坑。
I - Triple
題意:二元組$A<a, b>$ 三元組 $B<c, d, e> A * B = {<a, c, d> | <a, b> \in A , <c, d, e> \in B and b = e}$ 求有多少集合知足TOP(C)
思路:枚舉B,對於每一個B,咱們考慮符合條件的最高的a, 由於有多個a,那麼小的a確定不會放到集合裏面,
對於最大的a,咱們判斷二維BIT中右下角有的最大值,是否大於它自己,不是的話它就應該放進TOP(C)
要多考慮一下當前的(c, d) 有多個點的狀況
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 100010 5 #define pii pair <int, int> 6 #define ll long long 7 8 int t, n, m; 9 struct A 10 { 11 int a, b; 12 void scan() 13 { 14 scanf("%d%d", &a, &b); 15 } 16 bool operator < (const A &r) const 17 { 18 return b == r.b ? a < r.a : b < r.b; 19 } 20 }a[N]; 21 22 struct B 23 { 24 int c, d, e; 25 void scan() 26 { 27 scanf("%d%d%d", &c, &d, &e); 28 } 29 }b[N]; 30 31 pii pos[N]; 32 33 struct BIT 34 { 35 int a[1010][1010]; 36 37 void Init() 38 { 39 memset(a, 0, sizeof a); 40 } 41 42 void update(int x, int y, int val) 43 { 44 for (int i = x; i; i -= i & -i) 45 for (int j = y; j; j -= j & -j) 46 a[i][j] = max(a[i][j], val); 47 } 48 49 int query(int x, int y) 50 { 51 int res = 0; 52 for (int i = x; i < 1010; i += i & -i) 53 for (int j = y; j < 1010; j += j & -j) 54 res = max(res, a[i][j]); 55 return res; 56 } 57 }bit; 58 59 int main() 60 { 61 scanf("%d", &t); 62 for (int kase = 1; kase <= t; ++kase) 63 { 64 printf("Case #%d: ", kase); 65 scanf("%d%d", &n, &m); 66 for (int i = 1; i <= n; ++i) a[i].scan(); 67 for (int i = 1; i <= m; ++i) b[i].scan(); 68 sort(a + 1, a + 1 + n); 69 memset(pos, 0, sizeof pos); 70 for (int i = n; i >= 1; --i) 71 { 72 int b = a[i].b; 73 if (!pos[b].first) 74 { 75 pos[b].first = a[i].a, ++pos[b].second; 76 continue; 77 } 78 if (i != n) 79 { 80 if (b == a[i + 1].b && a[i].a == pos[b].first) 81 ++pos[b].second; 82 } 83 } 84 bit.Init(); 85 for (int i = 1; i <= m; ++i) 86 { 87 if (pos[b[i].e].first == 0) continue; 88 bit.update(b[i].c, b[i].d, pos[b[i].e].first); 89 } 90 ll res = 0; 91 for (int i = 1; i <= m; ++i) 92 { 93 int x = b[i].c, y = b[i].d; 94 if(!pos[b[i].e].first) continue; 95 int Max = max(bit.query(x, y + 1), bit.query(x + 1, y)); 96 bool flag = true; 97 if (Max >= pos[b[i].e].first) flag = false; 98 Max = bit.query(x, y); if (Max != pos[b[i].e].first) flag = false; 99 if (flag) res += pos[b[i].e].second; 100 } 101 printf("%lld\n", res); 102 } 103 return 0; 104 }
J - John's Fences
留坑。
K - Kykneion asma
留坑。
L - Number Link
留坑。
M - Meeting
題意:有多個集合,集合裏兩個點的距離都是$t-i$ 1 和 n 要到一個地方匯合,使得最大距離最小,求匯合點
思路:考慮暴力連邊的邊數最大有${\sum_{i = 1}^{i = m} S_i} ^2$ 無法解決
考慮將一個集合裏全部點向另外一個點連權值爲$t_i$的邊,再從這個點向集合裏全部點連權值爲0的邊
再對1和n分別跑最短路,枚舉中間點,更新答案
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 2000010 5 #define ll long long 6 #define INFLL 0x3f3f3f3f3f3f3f3f 7 8 int t, n, m; 9 int arr[N]; 10 11 struct Edge 12 { 13 int to, nx; ll w; 14 Edge() {} 15 Edge(int to, int nx, ll w) : to(to), nx(nx), w(w) {} 16 }edge[N << 1]; 17 18 int head[N], pos; 19 20 void Init() 21 { 22 memset(head, -1, sizeof head); 23 pos = 0; 24 } 25 26 void addedge(int u, int v, int w) 27 { 28 edge[++pos] = Edge(v, head[u], w); head[u] = pos; 29 } 30 31 struct node 32 { 33 int u; ll w; 34 node () {} 35 node (int u, ll w) : u(u), w(w) {} 36 bool operator < (const node &r) const 37 { 38 return w > r.w; 39 } 40 }; 41 42 ll dist[2][N]; 43 bool used[N]; 44 45 void Dijkstra(int st, int id) 46 { 47 for (int i = 1; i <= n + m; ++i) dist[id][i] = INFLL, used[i] = 0; 48 priority_queue <node> q; 49 q.emplace(st, 0); 50 dist[id][st] = 0; 51 while (!q.empty()) 52 { 53 int u = q.top().u; q.pop(); 54 if (used[u]) continue; 55 used[u] = 1; 56 for (int it = head[u]; ~it; it = edge[it].nx) 57 { 58 int v = edge[it].to; 59 if (!used[v] && dist[id][v] > dist[id][u] + edge[it].w) 60 { 61 dist[id][v] = dist[id][u] + edge[it].w; 62 q.emplace(v, dist[id][v]); 63 } 64 } 65 } 66 } 67 68 69 int main() 70 { 71 scanf("%d", &t); 72 for (int kase = 1; kase <= t; ++kase) 73 { 74 printf("Case #%d: ", kase); 75 scanf("%d%d", &n, &m); 76 Init(); 77 for (int i = 1, tot, w; i <= m; ++i) 78 { 79 scanf("%d%d", &w, &tot); 80 for (int j = 1; j <= tot; ++j) scanf("%d", arr + j); 81 for (int j = 1; j <= tot; ++j) addedge(arr[j], i + n, w); 82 for (int j = 1; j <= tot; ++j) addedge(i + n, arr[j], 0); 83 } 84 Dijkstra(1, 0); 85 Dijkstra(n, 1); 86 vector <int> v; 87 ll Min = INFLL; 88 // for (int i = 1; i <= n; ++i) cout << dist[0][i] << " " << dist[1][i] << endl; 89 for (int i = 1; i <= n; ++i) Min = min(Min, max(dist[0][i], dist[1][i])); 90 if (Min == INFLL) puts("Evil John"); 91 else 92 { 93 for (int i = 1; i <= n; ++i) if (max(dist[0][i], dist[1][i]) == Min) 94 v.push_back(i); 95 printf("%lld\n", Min); 96 for (int i = 0, len = v.size(); i < len; ++i) printf("%d%c", v[i], " \n"[i == len - 1]); 97 } 98 } 99 return 0; 100 }
C