• 北京化工大学2022-2023-1 ACM集训队每周程序设计竞赛(10)题解


    北大没做北化校赛血亏 

    离世界第一就差一个北化

    目录

    问题 A: 坤坤大闹天宫1

    问题 B: 坤坤大闹天宫2

    问题 C: 坤坤大闹天宫3

    问题 D: 坤坤大闹天宫4

    问题 E: 坤坤大闹天宫5

    问题 F: 坤坤大闹天宫6


     

    问题 A: 坤坤大闹天宫1

    难度指数:⭐⭐

    小思维

    因为X落在10^{9}

    我们设

    f(n)=n^{5}-(n-1)^{5}

    n大于120时,f(n)就大于10^{9}了,所以答案一定在[-120,120]

    直接跑一遍二重循环即可

    代码如下

    1. typedef long long ll;
    2. int main()
    3. {
    4. ll x;
    5. cin>>x;
    6. for(ll i=-120;i<=120;i++){
    7. for(ll j=-120;j<120;j++)
    8. if(i*i*i*i*i-j*j*j*j*j==x){
    9. cout<" "<
    10. return 0;
    11. }
    12. }
    13. return 0;
    14. }

    问题 B: 坤坤大闹天宫2

    难度指数:⭐

    直接按题目意思模拟即可

    代码如下

    1. int a[N];
    2. int main()
    3. {
    4. int n,k,t;
    5. cin>>n>>k;
    6. while(k--){
    7. cin>>t;
    8. while(t--){
    9. int kk;
    10. cin>>kk;
    11. a[kk]++;
    12. }
    13. }
    14. int ans=0;
    15. for(int i=1;i<=n;i++){
    16. if(a[i]==0) ans++;
    17. }
    18. cout<
    19. return 0;
    20. }

    问题 C: 坤坤大闹天宫3

    难度指数:⭐⭐

    因为n很小,只有12

    所以这是一道经典的搜索问题

    爆搜即可

    代码如下

    1. const int N=15;
    2. typedef long long ll;
    3. int n,m,x;
    4. int cost[N];
    5. int w[N][N];
    6. int v[N];
    7. int mincost=0x3f3f3f3f;
    8. int sumcost=0;
    9. void dfs(int u)
    10. {
    11. if(u==n) return;
    12. sumcost+=cost[u];//选择这本书u
    13. for(int i=0;i
    14. bool flag=1;
    15. for(int i=0;iif(v[i]0;
    16. if(flag)
    17. if(sumcost
    18. dfs(u+1);//进入下一本书的选择
    19. sumcost-=cost[u];
    20. for(int i=0;i
    21. dfs(u+1);//不选这本书u,进入下一本书的选择
    22. }
    23. int main()
    24. {
    25. cin>>n>>m>>x;
    26. for(int i=0;i
    27. {
    28. cin>>cost[i];
    29. for(int j=0;j>w[i][j];
    30. }
    31. dfs(0);
    32. if(mincost==0x3f3f3f3f) cout<<"-1";
    33. else cout<
    34. return 0;
    35. }

    问题 D: 坤坤大闹天宫4

    难度指数:⭐⭐⭐⭐

    这道题想法可以有很多

    这里说其中一种

    隔板法:n个球,就有n+1个隔板,除了最两边的隔板外,每删除一个隔板,相当于把相邻的球弄为一种颜色,最多有k个相邻,说明最多可以删除k个隔板,然后同一个隔板内部的可以视为一个整体,相当于一种颜色,第一个隔板内部有m个选择,第二个有m-1个选择,第三个也有m-1个选择,直到最后一个,所以公式就是

    \sum_{i=0}^{k}C_{n-1}^{i}*(m-1)^{(n-1-i)}*m

    代码如下:

    1. #include
    2. using namespace std;
    3. #define ll long long
    4. const int N = 2e5 + 10;
    5. const ll mod = 998244353;
    6. ll fact[N], infact[N];
    7. ll n, m, k;
    8. ll qmi(ll a, ll k, ll p) {
    9. int res = 1;
    10. while (k) {
    11. if (k & 1) res = (ll)res * a % p;
    12. a = (ll)a * a % p;
    13. k >>= 1;
    14. }
    15. return res;
    16. }
    17. void init() {
    18. fact[0] = infact[0] = 1;
    19. for (int i = 1; i < N; i++) {
    20. fact[i] = (ll)fact[i - 1] * i % mod;
    21. infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
    22. }
    23. }
    24. int main() {
    25. init();
    26. cin >> n >> m >> k;
    27. ll res = 0;
    28. for (int i = 0; i <= k; i++) {
    29. int a = n - 1, b = i;
    30. res = (ll)res + m * fact[a] % mod * infact[b] % mod * infact[a - b] %mod * qmi(m - 1, n - 1 - i, mod) % mod;
    31. res = res % mod;
    32. }
    33. cout << res << endl;
    34. }

    问题 E: 坤坤大闹天宫5

    难度指数:⭐⭐⭐

    贪心,判断括号匹配的字符串问题
    首先给出的所有字符串的左右括号数是要匹配的
    接下来判断这些字符串能否构成合理的括号序列,可以用pair存储每个字符串需要的匹配数和需要的右括号数

    我们试想,合法的括号序列一定是左括号尽量靠左,右括号靠右的,所以我们要对其就行排序,最后用一个变量记录当前的待匹配数res,如果pair 的右括号数超过待匹配数,则输出No

    代码如下:

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. #define pb push_back
    5. const int M = 1e5+7;
    6. char s[M];
    7. struct na{
    8. int x,y;
    9. bool operator <(const na &r)const
    10. {
    11. return y
    12. }
    13. };
    14. struct nb{
    15. int x,y;
    16. bool operator <(const nb &r)const
    17. {
    18. return x>r.x;
    19. }
    20. };
    21. vectorva;
    22. vectorvb;
    23. int main()
    24. {
    25. ios::sync_with_stdio(false);
    26. cin.tie(0);
    27. int n;
    28. cin>>n;
    29. for(int i=1;i<=n;i++)
    30. {
    31. cin>>s;
    32. int l=strlen(s);
    33. int a=0,b=0;
    34. for(int j=0;j
    35. {
    36. if(s[j]=='(')a++;
    37. else
    38. {
    39. if(a)a--;
    40. else b++;
    41. }
    42. }
    43. //这里a的意思是需要在这个字符串后面补多少右括号,b是需要在其前面补多少左括号
    44. //当a>b时,说明做左括号比右括号多,肯定优先放前面。显然,此时b越小在前面越优,因为需要在前面补左括号的个数就少了
    45. //a
    46. // cout<
    47. if(a>=b)va.pb(na{a,b});
    48. else vb.pb(nb{a,b});
    49. }
    50. sort(va.begin(),va.end());
    51. sort(vb.begin(),vb.end());
    52. bool f=true;
    53. int sm=0;
    54. for(int i=0;isize();i++)
    55. {
    56. sm-=va[i].y;
    57. if(sm<0)f=false;//前面的左括号能否满足当前字符串的需要
    58. sm+=va[i].x;//当前字符串所能提供的左括号
    59. //肯定是左括号需求量少的在前面
    60. }
    61. for(int i=0;isize();i++)
    62. {
    63. sm-=vb[i].y;
    64. if(sm<0)f=false;
    65. sm+=vb[i].x;
    66. //右边肯定是对称的来考虑,即需求后面右括号少的放在最右边
    67. }
    68. if(sm!=0)f=false;
    69. if(f)cout<<"Yes"<
    70. else cout<<"No"<
    71. return 0;
    72. }

    问题 F: 坤坤大闹天宫6

    难度指数:⭐⭐⭐⭐

    首先给出结论:后手必胜当且仅当这棵树有完美匹配

    (完美匹配:我们定义一组节点是两个节点且这两个节点间连一条边,如果一棵树可以分成若干个这样的组,那么说这棵树拥有完美匹配)

    这棵树有完美匹配的时候,因为先手染什么颜色后手只要染它的匹配,就能保证每个白色节点有至少一个与它相邻的黑色节点了

    如果一个点连着两个以上的叶子必定是先手必胜了,所以接下来我们默认所有的点连着的叶子个数小于等于1

    如果没有完美匹配,我们随便找一个点为根,然后对于一个叶子,先手把它的父亲染白,那么后手必须把这个叶子染黑。然后我们把这两个点从树中删去,继续操作。显然树不会被删完,否则就存在完美匹配了。此时我们随便染白一个还未染的点就赢了

    于是充要性都有了

    求完美匹配直接从叶子开始贪心

    代码如下

    1. #include
    2. #define int long long
    3. #define pb push_back
    4. #define fer(i,a,b) for(int i=a;i<=b;++i)
    5. #define der(i,a,b) for(int i=a;i>=b;--i)
    6. #define all(x) (x).begin(),(x).end()
    7. #define pll pair
    8. #define et cout<<'\n'
    9. #define xx first
    10. #define yy second
    11. using namespace std;
    12. template <typename _Tp>void input(_Tp &x){
    13. char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
    14. x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
    15. if(f)x=-x;
    16. }
    17. template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
    18. const int N=1e6+10;
    19. vector<int> v[N];
    20. int vis[N];
    21. void dfs(int son,int fa){
    22. for(auto t:v[son]){
    23. if(t==fa) continue;
    24. dfs(t,son);
    25. }
    26. if(!vis[son]&&vis[fa]){
    27. puts("First");
    28. exit(0);
    29. }
    30. if(!vis[son]){
    31. vis[son]=vis[fa]=1;
    32. }
    33. }
    34. signed main()
    35. {
    36. int n;
    37. cin>>n;
    38. fer(i,1,n-1){
    39. int a,b;
    40. cin>>a>>b;
    41. v[a].pb(b);
    42. v[b].pb(a);
    43. }
    44. vis[0]=1;
    45. dfs(1,0);
    46. puts("Second");
    47. }

  • 相关阅读:
    UE5 ChaosVehicles载具换皮 (连载二)
    Mac 切换 JDK 版本
    k8s-重启策略和健康检查
    linux服务器部署项目
    黑马程序员 MySQL数据库入门到精通——进阶篇(2)
    一款非常容易上手的报表工具,简单操作实现BI炫酷界面数据展示,驱动支持众多不同类型的数据库,可视化神器,免开源了
    计算机毕业设计ssm+vue基本微信小程序的体检预约小程序
    Elasticsearch跨集群检索配置
    IP-Guard桌面申请管理说明步骤
    docker搭建ELK
  • 原文地址:https://blog.csdn.net/m0_61735576/article/details/127803891