当前位置: 首页 > news >正文

SMU Winter 2025 div1 4th

文章目录

  • The Fourth Week
  • 一、前言
  • 二、算法
    • 1.贪心
      • <1>(2025暑假训练6 L2-2)
      • <2>(2025寒假训练3 C)
    • 2.二叉树
      • <1>(2025寒假训练6 L2-3)
    • 3. 深度优先搜索
      • <1>(2025寒假训练6 L2-3)
    • 4.排列组合
      • <1>(P10912 [蓝桥杯 2024 国 B] 数星星)
  • 三、总结


The Fourth Week

人生到处知何似,应似飞鸿踏雪泥。 ————苏轼

一、前言

OI赛制打得很糟糕。


二、算法

1.贪心

<1>(2025暑假训练6 L2-2)

天梯赛的赛场安排 25分、
题解:
给定n个学校的名称和人数,给定每个教室可以容纳的最大人数c。要想到直接把每个学校多余的人排序后放在新开辟的教室即可。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long

int n,c;
const int N = 5010;
int ct[N];
priority_queue<int>a;
map<string,int>mp;

signed main() {
    cin >> n >> c;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        string s; int x;
        cin >> s >> x;
        mp[s] = x/c;
        ans += mp[s];
        if(x%c) {
            a.push(x%c);
            cout << s << ' ' << mp[s]+1 << endl;
        }else cout << s << ' ' << mp[s] << endl;
    }int cnt = 0;
    while(!a.empty()) {
        int x = a.top(); a.pop();
        bool flag = true;
        for (int i = 0; i < cnt; i++) {
            if(ct[i] + x <= c) {
                ct[i] += x;
                flag = false;
                break;
            }
        }

        if(flag) ct[cnt++] = x;
    }cout << cnt+ans << endl;
}

<2>(2025寒假训练3 C)

题解:
平方差。我好像做过?
代码:

#include<iostream>

using namespace std;

int main() {
    long long l,r;
    long long ans = 0;
    cin >> l >> r;
    long long rr = 0,ll = 0;
    rr += (r+1)/2;
    rr += r/4;
    l--;
    ll += (l+1)/2;
    ll += l/4;
    cout << rr - ll << endl;
    return 0;
}

2.二叉树

<1>(2025寒假训练6 L2-3)

锦标赛 25分
下面还有一种做法
题解:
k轮锦标赛,依次给出每一轮的败者的能力值,最后给出胜者的能力值。输出n个数字表示n名选手的能力值。
代码:

#include <bits/stdc++.h>
using namespace std;
 
struct node {
    int win, lose;
};
 
bool flag = true;
 
void solve(node *t, int root, int size) {
    if (root * 2 > size || !flag) return;
    int gt = t[root * 2 + 1].lose > t[root * 2].lose ? root * 2 + 1 : root * 2;
    int le = t[root * 2 + 1].lose > t[root * 2].lose ? root * 2 : root * 2 + 1;
    if (t[gt].lose > t[root].win || t[le].lose > t[root].lose) {
        flag = false;
    } else if (t[gt].lose > t[root].lose) {
        t[gt].win = t[root].win;
        t[le].win = t[root].lose;
        solve(t, root * 2, size);
        solve(t, root * 2 + 1, size);
    } else {
        t[le].win = t[root].win;
        t[gt].win = t[root].lose;
        solve(t, root * 2, size);
        solve(t, root * 2 + 1, size);
        if (!flag) {
            flag = true;
            swap(t[le].win, t[gt].win);
            solve(t, root * 2, size);
            solve(t, root * 2 + 1, size);
        }
    }
}
 
int main() {
    int r;
    cin >> r;
    int l = (2 << (r - 1)) - 1;
    node tree[l + 1];
 
    for (int i = r; i > 0; --i) {
        int n = 1 << (i - 1);
        int s = (2 << (i - 1)) - n;
        while (n--) {
            cin >> tree[s].lose;
            s++;
        }
    }
    cin >> tree[1].win;
    if (tree[1].win < tree[1].lose) flag = false;
    else solve(tree, 1, l);
 
    if (!flag) cout << "No Solution";
    else {
        int n = 1 << (r - 1);
        int s = (2 << (r - 1)) - n;
        while (n--) {
            cout << tree[s].win << ' ' << tree[s++].lose;
            if (n) cout << ' ';
        }
    }
 
    return 0;
}

3. 深度优先搜索

<1>(2025寒假训练6 L2-3)

锦标赛 25分
OK啊又是这题,我比较偏向于深度优先搜索的方法,代码简单思维复杂一些
题解:
层层递归,俩者满足一个条件即可,具体看代码。
代码:

#include<bits/stdc++.h>

using namespace std;

const int N = 3e5 + 10;

int n;
vector<int> a(N);
vector<int> tmp(N),ans(N);

bool dfs(int u,int f){
    if(a[f] < a[u]) return false;
    if(u > (1 << n - 1)){
        int idx = u - (1 << n - 1);
        idx += idx - 1;
        tmp[idx] = a[u];
        tmp[idx + 1] = a[f];
        if(u == (1 << n)) ans = tmp;
        return true;
    }

    return (dfs(2 * u - 1,u) && dfs(2 * u,f)) || (dfs(2 * u - 1,f) && dfs(2 * u,u));
}
int main(){
    cin >> n;
    for(int i = n; i >= 1; --i)
        for(int j = (1 << i - 1) + 1; j <= (1 << i); ++j)
            cin >> a[j];
    cin >> a[1];


    if(!dfs(2,1)) cout << "No Solution";
    else{
        for(int i = 1; i <= (1 << n); ++i) cout << ans[i] << " ";
    }

    return 0;
}

4.排列组合

<1>(P10912 [蓝桥杯 2024 国 B] 数星星)

思路想到了,排列组合没写对,去精进一下。
题解:
对于l,r之间的每一个询问,查找度大于x的节点,并从中选取x-1个节点组成一颗星星即可,注意x是2的重复情况。
代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100000 + 5, mod = 1e9 + 7;
int n, d[N], L, R, ans, cur[N], vis[N];
ll fac[N], infac[N];
ll qpow(ll a, ll b) {
	ll res = 1;
	while (b) {
		if (b & 1) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}
ll inv(ll a) {
	return qpow(a, mod - 2);
}
void init(int n) {
	fac[0] = infac[0] = 1;
	for (int i = 1; i <= n; i++) {
		fac[i] = fac[i - 1] * i % mod;
		infac[i] = inv(fac[i]);
	}
}
ll C(ll a, ll b){
	if (a < b || a < 0 || b < 0) return 0;
	return fac[a] * infac[a - b] % mod * infac[b] % mod;
}
ll get(int a) {
	if (vis[a] == false) {
		vis[a] = true;
		for (int i = L - 1; i <= R - 1; i++) {
			cur[a] = (cur[a] + C(a, i)) % mod;
		}
		return cur[a];
	}
	else return cur[a];
}
int main() {
	cin >> n;
	for (int i = 1; i <= n - 1; i++) {
		int u, v;
		cin >> u >> v;
		d[u]++, d[v]++;	
	}
	cin >> L >> R;
	init(n);
	for (int i = 1; i <= n; i++) {
		ans = (ans + get(d[i])) % mod;
	}
	cout << ans << '\n';
	return 0;
} 

三、总结

整体都打得很糟糕,多方面因素。
OI赛制大多数题目都没有放上去。会做大多数都,但是看不到评测结果所以错的乱七八糟。
最后一周有时间可以再自主训练,多补补题。

相关文章:

  • Qt常用控件之日历QCalendarWidget
  • Docker(Nginx)部署Vue
  • UE5实现角色二段跳
  • deepseek_清华大学指导手册_pdf_1-5
  • C#基础:类的三大特性 之 封装
  • C++ ——— 模拟实现 AVL 树的插入
  • Win10配置VSCode的C/C++编译环境
  • 前后端分离系统架构:基于Spring Boot的最佳实践
  • 基于AT89C52单片机的出租车计价器
  • 【Linux进程一】进程的概念
  • CUDA专题1:CUDA介绍
  • Docker启动ES容器打包本地镜像
  • 基于RISC-V内核完全自主可控国产化MCU芯片
  • Shell脚本和Bat脚本区别
  • 我的世界地下城DLC开发的第二天
  • 第9章:LangChain结构化输出-示例2(数字提取服务)
  • 公开整理-最新中国城市统计NJExcel+PDF版本(1985-2024年)
  • B. Skibidus and Ohio
  • DeepSheek 本地部署
  • Service Worker 实现离线应用思路
  • 网上营销是做什么的/seo岗位是什么意思
  • 郑州网站建设更好/厦门seo代理商
  • 分类目录网站有哪些/最新热点新闻
  • 焦作建设银行门户网站/定制开发公司
  • 网站建设合同示范文本/快速seo排名优化
  • 网站名 注册/如何自己开发网站