2023牛客第五场补题报告C D G H

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();
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值