A、第k小数
快排看人品,欧皇就可以A,正解可以用STL里面的nth_element平均复杂度On,再来就是基数排序或者计数排序了
#include <bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; const ll MOD = 1e9 + 7; inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; } ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline int lowbit(int x) { return x & (-x); } const int N = 5e6 + 7; //被一开始2e6卡的死死的 int num[N]; int main() { int T = read(); while (T--) { int n = read(), k = read(); for (int i = 0; i < n; ++i) num[i] = read(); nth_element(num, num + k - 1, num + n); write(num[k - 1]), putchar(10); } return 0; }
B、不平行的直线
没有卡set的精度,正解开个set,统计不同斜率的个数即可,斜率不同,就会相交。
#include <bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; const ll MOD = 1e9 + 7; inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; } ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline int lowbit(int x) { return x & (-x); } const int N = 205; struct Node { int x, y; }a[N]; set<double> st; int main() { js; int n; cin >> n; for (int i = 1; i <= n; ++i) cin >> a[i].x >> a[i].y; for (int i = 1; i < n; ++i) for (int j = i + 1; j <= n; ++j) { if (a[j].x == a[i].x) { st.insert(999999999.0); continue; } double k = (a[j].y - a[i].y) * 1.0 / (a[j].x - a[i].x); st.insert(k); } cout << st.size() << endl; return 0; }
C、丢手绢
尺取
题目多了一行输入把我整半天……)看题目把
对于一个1-n的节点,选取另外一个点,起始为2,当从的最小距离小于的最小距离那么距离i的最远点不可能是,可以画个图,正反看一下就知道为什么不行了,那么对于i后方的点,可不可能更新到前面去?如果后面更新的最优解比不上前方的点,那么前面就已经保存了答案。使用前面更新的答案已经保存了。
#pragma GCC target("avx,sse2,sse3,sse4,popcnt") #pragma GCC optimize("O2,Ofast,inline,unroll-all-loops,-ffast-math") #include <bits/stdc++.h> using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; typedef unsigned long long ull; typedef long double ld; const ll MOD = 1e9 + 7; inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } inline void write(ll x) { if (!x) { putchar('0'); return; } char F[40]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; } ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline int lowbit(int x) { return x & (-x); } const int N = 1e5 + 7; int a[N], sum; int dis(int x, int y) { return a[y - 1] - a[x - 1]; } int mini(int x, int y) { return min(dis(x, y), sum - dis(x, y)); } int main() { int n = read(); for (int i = 1; i <= n; ++i) a[i] = read(), a[i] += a[i - 1]; sum = a[n]; int j = 2, ans = 0; for (int i = 1; i <= n; ++i) { while (j < n and mini(i, j) <= mini(i, j + 1)) ++j; ans = max(ans, mini(i, j)); } write(ans), putchar(10); return 0; }
D、二分
乌拉!看完雨巨讲解回来补题拉。突然发现这个题目居然挺简单的。
这个混乱的游戏,我们居然是吧裁判给出的条件转换为一个区间覆盖问题。求最多被覆盖的区间被几个区间覆盖了。
我这里看了别人的代码用的map去离散化,毕竟常数比较大,也可以用快排加去重,根据题目来吧,0x3f3f3f3f居然被卡了……瞬间就不好了,还是用下定义的宏吧……
#pragma GCC target("avx,sse2,sse3,sse4,popcnt") #pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math") #include <bits/stdc++.h> using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; typedef unsigned long long ull; typedef long double ld; const ll MOD = 1e9 + 7; inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; } inline void write(ll x) { if (!x) { putchar('0'); return; } char F[40]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; } ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline int lowbit(int x) { return x & (-x); } map<int, int> mp; int main() { js; int n; cin >> n; while (n--) { int num; char ch; cin >> num >> ch; if (ch == '.') ++mp[num], --mp[num + 1]; else if (ch == '+') ++mp[0], --mp[num]; else ++mp[num + 1], --mp[INT_MAX]; //……看来雨巨的数据很大0x3f3f3f3f死了 } int ans = INT_MIN; int sum = 0; for (auto it : mp) { sum += it.second; ans = max(ans, sum); } cout << ans << '\n'; return 0; }
E、交换
找循环节的裸题,赛后才发现,其实可以看到5 4 2 3 1,如果要把元素放到对应位置,5 1一个循环节,4 2 3一个循环节,一个循环节少换1次,总的就是少换循环节的个数次,因为不连续所以要开个map去记位置。当重新回来之后就说明一个循环节统计完毕
#include <bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; const ll MOD = 1e9 + 7; inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; } ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline int lowbit(int x) { return x & (-x); } const int N = 1e5 + 7; bool vis[N]; vector<int> v, v1; map<int, int> mp; int main() { int n = read(); for (int i = 0; i < n; ++i) { int x = read(); v.push_back(x); } v1 = v; sort(v1.begin(), v1.end()); for (int i = 0; i < n; ++i) mp[v1[i]] = i; int cnt = 0; for (int i = 0; i < n; ++i) { if (!vis[i]) { int j = i; while (!vis[j]) vis[j] = true, j = mp[v[j]]; ++cnt; } } write(n - cnt); return 0; }