牛客IOI周赛22-普及组
A. 战争尾声
题解
暴力通过:
坐标范围不大,尝试每个点也就是200*200
还需要查看所有的国家 是否 距离当前尝试的点 距离相等 200*200 * n (n最大200)
O(8000000)
暴力可过
Code
#include <iostream> #include <vector> #include <cmath> using namespace std; const double M = 1e-4; // 距离 double f(int x, int y, pair<int, int> p) { return (sqrt(pow(x - p.first, 2) + pow(y - p.second, 2))); } vector<pair<int, int>> v; int N; void solve() { for (int i = 1; i <= 200; i++) { for (int j = 1; j <= 200; j++) { int q = 0; double k = f(i, j, v[0]); // 求第一个点的距离 看后面的点是不是都相等 for (int p = 1; p < N; p++) { double kt = f(i, j, v[p]); if (fabs(kt - k) > M) // 浮点数判相等 { q = 1; break; } } if (q == 0) { cout << i << " " << j << endl; return; } } } cout << "War is cruel."; } int main() { cin >> N; for (int i = 0; i < N; i++) { int x, y; scanf("%d%d", &x, &y); v.push_back({x, y}); } solve(); return 0; }
B. 签订协议
题解
主要是超时,但AC代码也不难想
N最大10的6次方 所以N * N算法 和 N * NlongN 都是不行的
下面的是NlogN
观察样例1:
5 1 5 8 4 3
第一轮是8,8后面没有比他大的;所以需要第二轮:5 4 3 ,这三个之所以可以一轮完成,是因为 4的位置在5的后面,3的位置在4的后面;
故可将数与出现的位置练习起来,进行排序。
排完之后:
8 3 5 2 4 4 3 5 1 1
排完序之后的工作就成了找上升区间的个数
Code
#include <iostream> #include <queue> #include <algorithm> using namespace std; int main() { int N; cin >> N; vector<pair<int, int>> v; int x; for (int i = 0; i < N; i++) { scanf("%d", &x); v.push_back({x, i}); } // greater 从大到小排序 sort(v.begin(), v.end(), greater<pair<int, int>>()); int k = 1; for (int i = 0; i < N - 1; i++) { if (v[i + 1].second < v[i].second) k++; } cout << k; return 0; }
C. 照看小猫
题解
相当于是排列组合的分布原则(乘)
每个小猫名字的方案数乘其他小猫名字的方案数
乘的时候需要减去重复的
Code
#include <iostream> #include <cmath> #include <vector> #include <algorithm> using namespace std; using LL = long long; int main() { int N; cin >> N; int64_t sum = 1; int64_t a[15] = {0}; // 提前算了 for (int i = 1; i <= 10; i++) a[i] = int64_t(int64_t(pow(26, i)) % 77797 + a[i - 1]) % 77797; int v[N + 10]; for (int i = 0; i < N; i++) cin >> v[i]; sort(v, v + N); for (int i = 0; i < N; i++) { sum *= (a[v[i]] - i); // 这只小猫的情况数-之前小猫的数量 去掉了重复 sum %= 77797; } if (sum != 0) cout << sum; else cout << -1; return 0; }
D. 路线规划
模板题
#include <iostream> #include <vector> #include <algorithm> #include <numeric> using namespace std; using LL = long long; vector<LL> dp; struct node { LL x, y, t; bool operator<(const node e) { return t < e.t; } }; LL findt(LL x) { return dp[x] == x ? x : dp[x] = findt(dp[x]); } int main() { LL N, M; cin >> N >> M; dp.resize(N + 10); iota(dp.begin(), dp.end(), 0); LL x, y, t; vector<node> v; while (M--) { cin >> x >> y >> t; v.push_back({x, y, t}); } sort(v.begin(), v.end()); LL ans = 0; for (auto &e : v) { LL x = findt(e.x); LL y = findt(e.y); if (x == y) continue; ans += e.t; dp[x] = y; } cout << ans * 2; return 0; }