2023牛客第五场补题报告C D G H
C-Cheeeeen the Cute Cat_2023牛客暑期多校训练营5 (nowcoder.com)
思路
赛时乱搞了一个贪心水过去了,正解其实应该是以通过度数序列找到竞赛图的所有强连通分量。
代码
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
struct augment_path {
vector<vector<int> > g;
vector<int> pa; // 匹配
vector<int> pb;
vector<int> vis; // 访问
int n, m; // 两个点集中的顶点数量
int dfn; // 时间戳记
int res; // 匹配数
augment_path(int _n, int _m) : n(_n), m(_m) {
assert(0 <= n && 0 <= m);
pa = vector<int>(n, -1);
pb = vector<int>(m, -1);
vis = vector<int>(n);
g.resize(n);
res = 0;
dfn = 0;
}
void add(int from, int to) {
assert(0 <= from && from < n && 0 <= to && to < m);
g[from].push_back(to);
}
bool dfs(int v) {
vis[v] = dfn;
for (int u : g[v]) {
if (pb[u] == -1) {
pb[u] = v;
pa[v] = u;
return true;
}
}
for (int u : g[v]) {
if (vis[pb[u]] != dfn && dfs(pb[u])) {
pa[v] = u;
pb[u] = v;
return true;
}
}
return false;
}
int solve() {
while (true) {
dfn++;
int cnt = 0;
for (int i = 0; i < n; i++) {
if (pa[i] == -1 && dfs(i)) {
cnt++;
}
}
if (cnt == 0) {
break;
}
res += cnt;
}
return res;
}
};
int main()
{
int n;
scanf("%d",&n);
augment_path tmp(n,n);
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
int x;
scanf("%d",&x);
if(x) tmp.add(i-1,j-1);
}
}
cout<<tmp.solve()<<endl;
}
D-Cirno’s Perfect Equation Class_2023牛客暑期多校训练营5 (nowcoder.com)
思路
因为c也是b的倍数。所以直接枚举c的因数判断是否合法即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve();
signed main() {
// cin.sync_with_stdio(0);
// cin.tie(0);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}
void solve() {
int k, c, n;
cin >> k >> c >> n;
int ans = 0;
for (int b = 1; b * b <= c; b++) {
if (c % b == 0) {
if ((c - b) % k == 0) {
int a = (c - b) / k;
if (__gcd(a, b) >= n) ans++;
}
if (b * b != c && b != 1) {
int bb = c / b;
if ((c - bb) % k == 0) {
int a = (c - bb) / k;
if (__gcd(a, bb) >= n) ans++;
}
}
}
}
cout << ans << '\n';
}
G-Go to Play Maimai DX_2023牛客暑期多校训练营5 (nowcoder.com)
思路
可以直接双指针暴力扫一遍,只要当1,2,3,4的个数都满足要求时进行移动左指针即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve();
signed main(){
//cin.sync_with_stdio(0);
//cin.tie(0);
int T = 1;
//cin >> T;
while(T--){
solve();
}
return 0;
}
void solve(){
int n, k;
cin >> n >> k;
vector<int> a(n + 1);
for(int i = 1;i <= n;i++){
cin >> a[i];
}
vector<int> cnt(5, 0);
int l = 1, r = 1;
int cz = 0;
int ans = 0x3f3f3f3f;
while(r <= n){
while(r <= n && cz < 4){
if(a[r] < 4){
if(cnt[a[r]] == 0){
cz++;
}
}
else{
if(cnt[a[r]] == k - 1){
cz++;
}
}
cnt[a[r]]++;
r++;
}
while(l <= r && cz == 4){
ans = min(ans, r - l);
cnt[a[l]]--;
if(a[l] < 4){
if(cnt[a[l]] == 0){
cz--;
}
}
else{
if(cnt[a[l]] == k - 1){
cz--;
}
}
l++;
}
}
cout << ans << "\n";
}
H-Nazrin the Greeeeeedy Mouse_2023牛客暑期多校训练营5 (nowcoder.com)
思路
首先考虑到暴力枚举复杂度为 n 4 n^4 n4,考虑优化问题,其实我们其中的 n 2 n^2 n2复杂度是在枚举一段的背包,因此,我们完全可以预先处理出来每一段的01背包,复杂度 n 3 n^3 n3
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n, m;
int a[N];
int v[210], w[210];
int ba[210][210][210];
int f[N][210];
int sz[N];
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> v[i] >> w[i];
}
for (int l = 1; l <= n; l++) {
for (int i = l; i <= n; i++) {
for (int j = 0; j <= 200; j++) {
if (j >= v[i])
ba[l][i][j] = max(ba[l][i - 1][j], ba[l][i - 1][j - v[i]] + w[i]);
else
ba[l][i][j] = ba[l][i - 1][j];
}
}
}
for (int i = 1; i <= m; i++) cin >> sz[i];
int res = 0;
for (int i = max(m - 200 + 1, 1ll); i <= m; i++) {
for (int j = 0; j <= n; j++) {
if (j != 0)
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
else
f[i][j] = f[i - 1][j];
for (int k = 1; k <= j; k++) {
f[i][j] = max(f[i][j], f[i - 1][k - 1] + ba[k][j][sz[i]]);
}
res = max(f[i][j], res);
}
}
cout << res << "\n";
}
signed main() {
IOS;
int t = 1;
// cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}