首页 > 其他分享 >牛客练习赛122

牛客练习赛122

时间:2024-03-03 11:48:03浏览次数:30  
标签:std 练习赛 int cin long kN 牛客 122 mp

目录

写在前面

比赛地址:https://ac.nowcoder.com/acm/contest/75768

因为 suzt 大神在打所以也来凑一凑热闹。

A

签到。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int n, m;
  std::cin >> n >> m;
  while (n --) {
    int c = 0;
    for (int i = 1; i <= m; ++ i) {
      int x; std::cin >> x;
      c += (x == 1 ? 1 : -1);
    }
    std::cout << abs(c) << "\n";
  }
  return 0;
}

B

签到。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 1e5 + 10;
//=============================================================
int n, a[kN], b[kN], p[kN];
//=============================================================
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    std::cin >> n;
    for (int i = 1; i <= n; ++ i) std::cin >> a[i];
    for (int i = 1; i <= n; ++ i) p[i] = 0;
    int flag = 1;
    for (int i = 1; i <= n; ++ i) {
      std::cin >> b[i];
      if (p[a[i]] == 0) p[a[i]] = b[i];
      else if (p[a[i]] != b[i]) flag = 0;
    }
    std::cout << (flag ? "Yes\n" : "No\n");
  }
  return 0;
}

C

设 \(n\le m\),手玩下发现 \(n= 1\) 无解,\(n=2\) 只可以往一个方向跳,\(m \ge 4\) 时所有位置均可遍历到,于是给小范围打个表即可。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
int ans[5][5] = {
  0, 0, 0, 0, 0,
  0, 0, 0, 0, 0,
  0, 0, 0, 1, 1,
  0, 0, 1, 8, 12,
  0, 0, 1, 12, 16
};
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    int n, m; std::cin >> n >> m;
    if (n <= 1 || m <= 1) {
      std::cout << 1 << "\n";
      continue;
    }
    if (n == 2 || m == 2) {
      if (n != 2) std::swap(n, m);
      std::cout << 1 + (m - 1) / 2 << "\n";
      continue;
    }
    if (n <= 4 && m <= 4) {
      std::cout << ans[n][m] << "\n";
      continue;
    }
    std::cout << 1ll * n * m << "\n";

  }
  return 0;
}

D

区间 DP

发现将圆直接断开没有影响,问题变为给定 \(m\) 条线段,要求这些线段之间要么相互包含要么没有任何交点,求少能删多少。

可能有重复线段,先预处理 \(g_{l, r}\) 表示端点为 \(l, r\) 的线段中权值最大的。

考虑求最多能保留多少,考虑区间 DP,设 \(f_{l, r}\) 表示完全位于区间 \([l, r]\) 的线段最多能保留多大的价值,初始化 \(\forall 1\le i\le n, f_{i, i}=0\)。枚举分界点的区间 DP 转移显然只能是 \(O(n^3)\) 的,绝对跑不过去,但对于此题发现转移时仅需考虑线段的端点即可覆盖所有有贡献的分界点,于是考虑按长度枚举区间,有如下三种转移:

  • \(\max(f_{l + 1, r}, f_{l, r - 1}) \rightarrow f_{l, r}\),表示不新增区间的贡献,继承更小区间的答案即可。
  • \(f_{l + 1, r - 1} + g_{l, r} \rightarrow f{l, r}\),新增一条最外层的线段。
  • 维护集合 \(s_r\) 表示右端点为 \(r\) 的左端点的数量,则 \(\forall p\in s_r,\ f_{l, p - 1} + f_{l, r}\) 表示新增没有交点的线段的贡献。

发现第三种转移总共只会进行 \(O(nm)\) 次,其他转移每轮只会进行常数次,则总时间复杂度 \(O(n^2 + nm)\) 级别。

//区间 DP
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
#define pii std::pair<int,int>
#define mp std::make_pair
const int kN = 2e3 + 10;
const LL kInf = 1e18 + 2077;
//=============================================================
int n, m;
LL s, f[kN][kN];
std::map <pii, pii> maxw;
std::vector <int> v[kN];
//=============================================================
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  std::cin >> n >> m;
  for (int i = 1; i <= m; ++ i) {
    int l, r, w; std::cin >> l >> r >> w;
    if (l > r) std::swap(l, r);
    s += 1ll * w;
    if (maxw.count(mp(l, r))) {
      if (maxw[mp(l, r)].first < w) maxw[mp(l, r)] = mp(w, l);
    } else {
      maxw[mp(l, r)] = mp(w, l);
    }
  }

  for (int i = 1; i <= n; ++ i) {
    for (int j = 1; j < n; ++ j) {
      if (!maxw.count(mp(j, i))) continue;
      v[i].push_back(j);
    }
  }
  
  for (int len = 2; len <= n; ++ len) {
    for (int l = 1, r = l + len - 1; r <= n; ++ l, ++ r) {
      f[l][r] = f[l + 1][r - 1];
      f[l][r] = std::max(f[l][r], std::max(f[l + 1][r], f[l][r - 1]));
      if (maxw.count(mp(l, r))) {
        f[l][r] = std::max(f[l][r], f[l - 1][r + 1] + maxw[mp(l, r)].first);
      }
      for (auto x: v[r]) {
        if (x < l) continue;
        f[l][r] = std::max(f[l][r], f[l][x - 1] + f[x][r]);
        f[l][r] = std::max(f[l][r], f[l][x - 1] + f[x + 1][r - 1] + maxw[mp(x, r)].first);
      }
    }
  }
  std::cout << s - f[1][n];
  return 0;
}
/*
6 6
1 4 1
2 5 1
3 6 1
4 1 1
5 2 1
6 3 1

6 6
1 2 1
2 4 5
2 3 1
3 4 1
4 5 1
5 6 1
*/

E

上课再写吸吸

写在最后

学到了什么

  • D:我草区间 DP 有 \(O(n^2)\) 的太牛逼了,考虑区间合并时根据性质仅考虑有贡献的区间分界点。
  • E

标签:std,练习赛,int,cin,long,kN,牛客,122,mp
From: https://www.cnblogs.com/luckyblock/p/18049757

相关文章

  • 牛客练习赛122题解A-D
    牛客练习赛122A.黑白配代码:#include<bits/stdc++.h>usingnamespacestd;constintMAXN=1e5+7;constintINF=0x3f3f3f3f;typedeflonglongll;#defineendl"\n"voidsolve(){ intt,n;cin>>t>>n;inta[n+1];while(t--)......
  • 牛客练习赛122 F 括号匹配 费用流
    CF打多了很多题目中的性质都挖掘出来了,也想到了费用流。很难\(dp\)因为一组中三个括号留下来一个很难作为状态进行dp。由于对括号匹配还不熟悉以为是\(n^2\)的图就没写了,事实上应该是线性的建图。所以对于\(n=2000\)这个数据范围网络流是可以过的。设置源点\(S\)和汇点\(T\)。......
  • 牛客练习赛122 (小白登山记)
    A.黑白配思路:n个学生手心和手背分为2个组求出他们的差直接按题意写即可Code:#include<bits/stdc++.h>usingnamespacestd;intmain(){intn,m;cin>>n>>m;for(inti=0;i<n;++i){intcnt1=0,cnt0=0;for(intj=0......
  • 代码随想录算法训练营第三十二天 | 45.跳跃游戏II ,55. 跳跃游戏,122.买卖股票的最佳时
     122.买卖股票的最佳时机II 已解答中等 相关标签相关企业 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购......
  • 2024牛客寒假算法基础集训营6 题解 ( A,B,C,D,E,I)
    2024牛客寒假算法基础集训营6题解(A,B,C,D,E,I)A 宇宙的终结题意找到\([l,r]\)区间中有多少数恰好等于三个不同素数的乘积思路数据范围很小,可以考虑暴力,遍历\([l,r]\)区间内每个数,拿每个小于当前数的素数一直往下除,判断是否存在能被恰好3个素数整除的情况代码/********......
  • 2024牛客寒假算法基础集训营5 题解 ( A,C,G,H,I,L,M )
    2024牛客寒假算法基础集训营5题解(A,C,G,H,I,L,M)A mutsumi的质数合数题意有一个由\(n\)个正整数组成的数组,她想知道数组中质数和合数共有几个。思路由质数和合数的定义可知,正整数范围内除\(1\)外,要么是质数要么是合数,本题直接统计不是\(1\)的正整数的个数即可代码......
  • 1224本周补题
    P1142轰炸-洛谷|计算机科学教育新生态(luogu.com.cn)似乎数据有点小,三重循环都能过,也可以整个map然后二次循环枚举最后遍历一次也可以,特别注意的是最开始我枚举的斜率,实际上在题目要求之下需要的是三点共线,只是斜率相等并不能满足题意。#include<bits/stdc++.h>usingnam......
  • 2024牛客寒假算法基础集训营1(补题)
    目录ABCDEFGHIKLAn的范围很小暴力直接\(O(n^3)\)直接做就行。我还傻的统计了一下前后缀,不过怎么写都行这道题。#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(inti=(a);i>=(b);--i)#d......
  • 2024牛客寒假算法基础集训营4
    2024牛客寒假算法基础集训营4A 柠檬可乐题意根据给定的\(a\)和\(b\),判断是否\(a\gek\timesb\)思路题意非常直接代码/*******************************|Author:AlwaysBeShine|Problem:柠檬可乐|Contest:NowCoder|URL:https://ac.nowcoder.com/acm/......
  • 牛客周赛 Round 34
    牛客周赛Round34比赛链接感觉比以往难度有些大,但是大佬们该强的还是很强啊小红的字符串生成思路就两个字符,如果字符相同只能组成两种,不同则可以组成四种Code#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#defineall(x)x.begin()+1,x.end()#de......