补一下牛客,菜得发昏了,F搞了两个小时都没搞出来,不如去开H了
还没补完 剩下的打了atc再来
文章目录
- 牛客 寒假集训1A DFS搜索
- 牛客 寒假集训1B 关鸡
- 牛客 寒假集训1C 按闹分配
- 牛客 寒假集训1D 数组成鸡
- 牛客 寒假集训1E 本题又主要考察了贪心
- 牛客 寒假集训1G why买外卖
- 牛客 寒假集训1H 01背包,但是bit
牛客 寒假集训1A DFS搜索
题目链接
看数据很小于是纯暴力解法
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 1000010;void solve()
{int n;cin >> n;string s;cin >> s;bool flag1 = false, flag2 = false;for (int i = 0; i < n; i ++ ){if (s[i] == 'd'){for (int j = i + 1; j < n; j ++ ){if (s[j] == 'f'){for (int k = j + 1; k < n; k ++ ){if (s[k] == 's'){flag1 = true;break;}}if (flag1) break;}}if (flag1) break;}}for (int i = 0; i < n; i ++ ){if (s[i] == 'D'){for (int j = i + 1; j < n; j ++ ){if (s[j] == 'F'){for (int k = j + 1; k < n; k ++ ){if (s[k] == 'S'){flag2 = true;break;}}if (flag2) break;}}if (flag2) break;}}if (flag2) cout << 1 << ' ';else cout << 0 << ' ';if (flag1) cout << 1 << '\n';else cout << 0 << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}
牛客 寒假集训1B 关鸡
题目链接
我是分两种讨论,从左边出去和从右边出去,先把坐标按y从小到大排序,遍历每一个坐标,看下一个坐标是不是在当前坐标的下面或者右下面或者右上面,是的话当前这一端就封死了
答案最大是3(在鸡的左右下)
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 1000010;bool cmp(PII a, PII b)
{if (a.second != b.second) return a.second < b.second;else return a.first < b.first;
}void solve()
{int n;cin >> n;vector<PII> pos(n);int cnt = 0;for (int i = 0; i < n; i ++ ){cin >> pos[i].first >> pos[i].second;if (pos[i].first == 1 && pos[i].second == -1) cnt ++ ;if (pos[i].first == 1 && pos[i].second == 1) cnt ++ ;if (pos[i].first == 2 && pos[i].second == 0) cnt ++ ;}sort(pos.begin(), pos.end(), cmp);if (n == 0){cout << 3 << '\n';return;}if (cnt == 3){cout << 0 << '\n';return;}bool flag1 = false, flag2 = false;for (int i = 0; i < n - 1; i ++ ){int x = pos[i].first, y = pos[i].second;if (y < 0){if (flag1) continue;if (x == 1){if (pos[i + 1].first == 2 && (pos[i + 1].second == y || pos[i + 1].second == y + 1)) flag1 = true;}else{if (pos[i + 1].first == 1 && pos[i + 1].second == y + 1) flag1 = true;}}else{if (flag2) break;if (x == 1){if (pos[i + 1].first == 2 && (pos[i + 1].second == y || pos[i + 1].second == y + 1)) flag2 = true;}else{if (pos[i + 1].first == 1 && pos[i + 1].second == y + 1) flag2 = true;}}}if (flag1 && flag2) cout << 0 << '\n';else if (flag1){int x = pos[n - 1].first, y = pos[n - 1].second;if (y >= 0) cout << 1 << '\n';else cout << 2 << '\n';}else if (flag2){int x = pos[0].first, y = pos[0].second;if (y <= 0) cout << 1 << '\n';else cout << 2 << '\n';}else{int ans = 0;int x1 = pos[0].first, y1 = pos[0].second;int x2 = pos[n - 1].first, y2 = pos[n - 1].second;if (y1 <= 0) ans ++ ;else ans += 2;if (y2 >= 0) ans ++ ;else ans += 2;ans = min((i64)3, min(ans, 3 - cnt));cout << ans << '\n';}
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}
牛客 寒假集训1C 按闹分配
题目链接
不知道为啥赛时脑抽写二分,实际上 O ( n ) O(n) O(n) 处理一下前缀和就搞定了
鸡插到某一个人前面,那增加的不满意度就是 t c t_c tc 乘上在鸡后面的人数,根据这个就能算出鸡最优能站在第几个人前面,剩下的前缀和就搞定了
下面代码还是二分,懒得写qaq
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 1000010;void solve()
{int n, q, c;cin >> n >> q >> c;vector<int> t(n + 1), pre(n + 1), tmp(n + 2);for (int i = 1; i <= n; i ++ ) cin >> t[i], pre[i] = pre[i - 1] + t[i];for (int i = 1; i <= n; i ++ ) pre[i] = pre[i - 1] + pre[i];sort(t.begin(), t.end());for (int i = 1; i <= n + 1; i ++ ) tmp[i] = tmp[i - 1] + t[i - 1];while (q -- ){int m;cin >> m;auto check = [&](int mid){int pos = upper_bound(tmp.begin(), tmp.end(), mid) - tmp.begin() - 1;int time = pre[n] + (n - pos + 1) * c;if (time - pre[n] > m) return false;else return true;};int l = 0, r = pre[n];while (l < r){int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;}cout << r + c << '\n';}
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;// cin >> t;while (t -- ){solve();}
}
牛客 寒假集训1D 数组成鸡
题目链接
这题又可以学到一个trick,m的范围在1e9之内,但是30个2相乘就已经超过了,所以n给那么大完全是吓唬人的,如果n很大,那只能说明有很多一样的数要变成1 or -1,所以枚举每一个数变成-1开始到更小,从1开始到更大,只要乘积超过1e9直接停就可以了,最后要注意,如果一个数是0,乘积就肯定是0,所以0是很容易达成的,直接在一开始把0加入到可以得到的集合中,之后询问时每次查找集合中有没有这个数就可以了
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 1000010;
const int maxn = 1e6;
const int mod = 1e9 + 7;void solve()
{int n, q;cin >> n >> q;vector<int> a(n);for (int i = 0; i < n; i ++ ) cin >> a[i];sort(a.begin(), a.end());set<int> st;st.insert(0);auto check = [&](int x){int res = 1;for (int i = 0; i < n; i ++ ){res *= a[i] + x;if (res > 1e9) return false;}st.insert(res);return true;};for (int i = 0; i < n; i ++ ){if (i != n - 1 && a[i] == a[i - 1]) continue;for (int j = -a[i] - 1; check(j); j -- ) ;for (int j = -a[i] + 1; check(j); j ++ ) ;}while (q -- ){int m;cin >> m;cout << (st.count(m) ? "Yes" : "No") << '\n';}
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;// cin >> t;while (t -- ){solve();}
}
牛客 寒假集训1E 本题又主要考察了贪心
题目链接
数据范围很小,dfs就可以
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 1000010;void solve()
{int n, m;cin >> n >> m;vector<int> a(n + 1);for (int i = 1; i <= n; i ++ ) cin >> a[i];vector<PII> op;for (int i = 0; i < m; i ++ ){int x, y;cin >> x >> y;if (x == 1 || y == 1) a[1] += 3;else op.push_back(make_pair(x, y));}int ans = n;m = op.size();function<void(int)> dfs = [&](int u){if (u == m){int cnt = 0;for (int i = 2; i <= n; i ++ ){if (a[i] > a[1]) cnt ++ ;}ans = min(cnt + 1, ans);return;}int id1 = op[u].first, id2 = op[u].second;a[id1] ++ , a[id2] ++ ;dfs(u + 1);a[id1] += 2, a[id2] -- ;dfs(u + 1);a[id1] -= 3, a[id2] += 3;dfs(u + 1);a[id2] -= 3;};dfs(0);cout << ans << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}
牛客 寒假集训1G why买外卖
题目链接
优惠券按照a排序,遍历一遍即可,利用前缀和
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 1000010;bool cmp(PII a, PII b)
{if (a.first != b.first) return a.first < b.first;else return a.second > b.second;
}void solve()
{int n, m;cin >> n >> m;vector<PII> info(n);for (int i = 0; i < n; i ++ ) cin >> info[i].first >> info[i].second;sort(info.begin(), info.end(), cmp);int pre = 0;int i = 0, ans = m;for (i = 0; i < n; i ++ ){pre += info[i].second;if (info[i].first - pre > m) continue;else{int used = info[i].first - pre;ans = max(ans, info[i].first + m - used);}}cout << ans << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}
牛客 寒假集训1H 01背包,但是bit
题目链接
按照题解思路写的,枚举m的二进制中的每一位1,让最后的总重量在该位为0,在这一位之后的可以随便取,在这一位之前的必须是m的子集(意思是m那一位不为1的,总重量的那一位也不能为1),取最大值即可
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 1000010;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;void solve()
{int n, m;cin >> n >> m;vector<int> v(n), w(n);for (int i = 0; i < n; i ++ ) cin >> v[i] >> w[i];int ans = 0;for (int j = 0; j < n; j ++ ){bool flag = true;for (int k = 0; k <= 30; k ++ ){if ((((w[j] >> k) & 1) == 1) && (((m >> k) & 1) == 0)){flag = false;break;}}if (flag) ans += v[j];}for (int i = 0; i <= 30; i ++ ){if ((m & (1 << i)) == 0) continue;int tmp = 0;for (int j = 0; j < n; j ++ ){bool flag = true;if (((w[j] >> i) & 1) == 1) continue;for (int k = i + 1; k <= 30; k ++ ){if ((((w[j] >> k) & 1) == 1) && (((m >> k) & 1) == 0)){flag = false;break;}}if (flag) tmp += v[j];}ans = max(ans, tmp);}cout << ans << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}