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

ZISUOJ 2024算法基础公选课练习二

一、前言

先把代码丢上来,后续再补上思路

二、题目总览

ac162b2f392f4cb5bba5db987f3f7bef.png

三、具体题目

3.1 问题 A: 成绩排序1

3135011fc36d4ce4ae746167e43ba568.png

参考代码

简单排序

#include <bits/stdc++.h>
using i64 = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int t = 1;
    std::cin >> t;
    while(t--) {
        int n;
        std::cin >> n;
        std::vector<int> v(n);
        for(auto &vi:v) std::cin >> vi;
        std::sort(v.begin(),v.end(),[&](const int &num1,const int &num2) {
            return num1>num2;
        });
        for(int i = 0;i<n;i++) std::cout << v[i] << " \n"[i==n-1];
    }
    
    return 0;
}

3.2 问题 B: 数字和排序

3d1b1eb404f648da997ede216d19cd63.png

参考代码

简单排序

#include <bits/stdc++.h>
using i64 = long long;
using pii = std::pair<int,int>;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int n = 1;
    while(std::cin >> n) {
        if(n==0) break;
        std::vector<pii> v(n);
        for(int i = 0;i<n;i++) {
            int num;std::cin >> num;
            int tmp = num,sum = 0;
            while(tmp!=0) {
                sum+=tmp%10;
                tmp/=10;
            }
            v.emplace_back(sum,num);
        }
        std::sort(v.begin(),v.end(),[&](const pii& p1,const pii& p2) {
            if(p1.first!=p2.first) return p1.first>p2.first;
            return p1.second > p2.second;
        });
        for(int i = 0;i<n;i++) {
            std::cout << v[i].second << " \n"[i==n-1];
        }

    }
    
    return 0;
}

3.3 问题 C: 帆帆的挂件

e6237a365218498ab6cf1ce16e9b0f27.png

参考代码

简单模拟

#include <bits/stdc++.h>
using i64 = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int n,x_0;
    std::cin >> n >> x_0;
    std::vector<int> a(n),b(n);
    for(auto &ai:a) std::cin >> ai;
    for(auto &bi:b) std::cin >> bi;
    int ans = 0;
    for(int i = 0;i<n;i++) {
        if(x_0>=a[i]) {
            x_0+=b[i];
            ++ans;
        }
    }
    std::cout << ans << '\n';
    
    return 0;
}

3.4 问题 D: 文件名排序

aa95c4f631f14b6f8481e5829e7ed0be.png

参考代码

stringstream很好处理这种读入情况

#include <bits/stdc++.h>
using i64 = long long;
using pss = std::pair<std::string,std::string>;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    std::string line;
    std::vector<pss> v;
    while(std::getline(std::cin,line)) {
        std::stringstream ss(line);
        std::string tmp1,tmp2;
        while(ss >> tmp1 >> tmp2) v.emplace_back(tmp2,tmp1);
    }
    std::sort(v.begin(),v.end());
    for(const auto &vi:v) {
        std::cout << vi.second << ' ' << vi.first << '\n';
    }
    
    return 0;
}

3.5 问题 E: 火星数排序

2bae9a1544da4ce98b2488b9261fd77b.png

参考代码

可以用哈希表映射过去,写题的时候脑子犯昏,写了好多if

#include <bits/stdc++.h>
using namespace std;
struct number{
	int en;
	int mn;
}a[1000];

int earth(int n){
	int temp=n;
	int total = 0;
	int sum[20];
	int index = 0;
	while(temp != 0){
		if(temp%10==0){
			sum[index] = 0;
		}else if(temp%10==8){
			sum[index] = 1;
		}else if(temp%10==1){
			sum[index] = 2;
		}else if(temp%10==5){
			sum[index] = 3;
		}else if(temp%10==2){
			sum[index] = 4;
		}else if(temp%10==3){
			sum[index] = 5;
		}else if(temp%10==9){
			sum[index] = 6;
		}else if(temp%10==4){
			sum[index] = 7;
		}else if(temp%10==7){
			sum[index] = 8;
		}else if(temp%10==6){
			sum[index] = 9;
		}
		index++;
		temp /= 10;
	}
	for(int i = index-1;i>=0;i--) total = total*10+sum[i];
	return total;
}


bool cmp1(number a,number b){
	return a.en<b.en;
}
int main(){
    cin.tie(nullptr)->sync_with_stdio(false);

	int Case;
	cin>>Case;
	for(int i=0;i<Case;i++){
		int j=0;
		int n;cin >> n;
		for(int j = 0;j<n;j++) cin >> a[j].mn;

		for(int j = 0;j<n;j++) a[j].en = earth(a[j].mn);
		sort(a,a+n,cmp1);

		for(int j = 0;j<n;j++){
			if(j==0) cout << a[j].mn;
			else cout << ' ' << a[j].mn;
		}
		cout << '\n';
	}
	
	
	return 0;
}

3.6 问题 F: 帆帆的数位计算

fc254ef556cb4911804d7ae33dd2d48b.png

参考代码

写个循环模拟就行,我当时想复杂了

#include <bits/stdc++.h>
using i64 = long long;

void dfs(std::string num,int step) {
    if(num.size()==1) {
        std::cout << step << '\n';
        return;
    }
    int sum = 0;
    for(const auto &c:num) {
        sum+=c^48;
    }
    dfs(std::to_string(sum),step+1);
}
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    std::string num;
    std::cin >> num;
    dfs(num,0);
    
    return 0;
}

3.7 问题 G: 帆帆的数列

a3cbc26be75d4db798b84107f9cded02.png

参考代码

前缀和+贪心

#include <bits/stdc++.h>
using i64 = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int t = 1;
    std::cin >> t;
    while(t--) {
        int n,m;
        std::cin >> n;
        std::vector<int> a(n+1,0),preA(n+1,0);
        for(int i = 1;i<=n;i++) {
            std::cin >> a[i];
            preA[i] = preA[i-1]+a[i];
        }
        std::cin >> m;
        std::vector<int> b(m+1,0),preB(m+1,0);
        for(int i = 1;i<=m;i++) {
            std::cin >> b[i];
            preB[i] = preB[i-1]+b[i];
        }

        int ans = 0;
        for(int i = 0;i<=n;i++) {
            for(int j = 0;j<=m;j++) {
                ans = std::max(ans,preA[i]+preB[j]);
            }
        }
        std::cout << ans << '\n';
    }
    
    return 0;
}

3.8 问题 H: 帆帆的糖

dff4f2074e4f45a4978112b343c80389.png

参考代码

一开始当成dfs写了,没看到范围,真是蠢了。可以直接二分枚举答案,不能直接暴力,会TLE

#include <bits/stdc++.h>
using i64 = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int n,k;
    std::cin >> n >> k;
    int ans = 0;
    int low = 1,high = n;
    
    while(low<high) {
        int mid = (low+high)>>1;
        if(1LL*(1+mid)*mid/2-(n-mid)>=k) {
            high = mid;
        }else {
            low = mid+1;
        }
    }
    std::cout << n-low << '\n';

    return 0;
}

3.9 问题 I: Determine the Photo Position

90509c8110e9494a999386473f63cd7f.png

参考代码

前缀和

#include <bits/stdc++.h>
using i64 = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int n,m;
    std::cin >> n >> m;
    std::vector<std::vector<char>> g(n+5,std::vector<char>(n+5));
    std::vector<std::vector<int>> pre(n+5,std::vector<int>(n+5,0));
    for(int i = 1;i<=n;i++) {
        for(int j = 1;j<=n;j++) {
            std::cin >> g[i][j];
            pre[i][j]=pre[i][j-1]+(g[i][j]^48);
        }
    }

    std::string t;std::cin >> t;

    int ans = 0;
    for(int i = 1;i<=n;i++) {
        for(int j = m;j<=n;j++) {
            if(pre[i][j]-pre[i][j-m]==0) {
                ++ans;
            }
        }
    }
    std::cout << ans << '\n';

    return 0;
}

3.10 问题 J: Ball Dropping

6d3e1820e72f4b03b807428c87d94187.png

参考代码

初中数学计算

#include <bits/stdc++.h>
using i64 = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    double r,a,b,h;
    std::cin >> r >> a >> b >> h;
    if(2*r<=b) {
        std::cout << "Drop\n";
        return 0;
    }
    double h0 = std::sqrt(h*h+((a-b)/2)*((a-b)/2));
    double sin = ((a-b)/2)/h0;
    double cos = h/h0;
    double tan = ((a-b)/2)/h;
    double x1 = r*sin,x2 = (r*cos-b/2)/tan;

    std::cout << "Stuck\n";
    std::cout << std::fixed << std::setprecision(10) << x1+x2 << '\n';

    return 0;
}

3.11 问题 K: Cut the Tree

c8a12463fc934044acd4f796c3019b0c.png

参考代码

套了别人的两个模板,链式前向星和带权的线段树+dfs找树上LIS,注意数组不能开太大也不能开太小

#include <bits/stdc++.h>
using i64 = long long;
using pii = std::pair<int,int>;
constexpr int N = 1e5+5,M = N,INF = 0x3f3f3f3f;

//链式前向星
int head[N];
int val[N];
int n;
int ans;

struct edge{
	int next, to, w;
}e[N << 1];
int cnt;

void init(){
	for(int i = 0; i <= n; i++)
		head[i] = -1;
	cnt = 0;
}

void add(int u, int v, int w = 0){
	e[cnt].w = w;
	e[cnt].to = v;
	e[cnt].next = head[u];
	head[u] = cnt++;
}

//带权线段树+dfs找LIS
int tot;
struct Tree{
	int l, r;
	int lis, lds;
}tree[N * 100];
int rt[N];
int sz[N];
int root, maxPart;
int res;
int vis[N];
void getrt(int S, int u, int f){
	sz[u] = 1;
	int maxx = 0;
	for(int i = head[u]; ~i; i = e[i].next){
		int v = e[i].to;
		if(vis[v] || f == v)
			continue;
		getrt(S, v, u);
		sz[u] += sz[v];
		maxx = std::max(maxx, sz[v]);
	}
	maxx = std::max(maxx, S - sz[u]);
	if(maxx < maxPart){
		maxPart = maxx;
		root = u;
	}
}
int build(){
	tot++;
	tree[tot].l = tree[tot].r = tree[tot].lis = tree[tot].lds = 0;
	return tot;
}
void update(int &p, int l, int r, int pos, int vlis, int vlds){
	if(p == 0)
		p = build();
	tree[p].lis = std::max(tree[p].lis, vlis);
	tree[p].lds = std::max(tree[p].lds, vlds);
	if(l == r)
		return ;
	int m = (l + r) >> 1;
	if(pos <= m)
		update(tree[p].l, l, m, pos, vlis, vlds);
	else
		update(tree[p].r, m+1, r, pos, vlis, vlds);
}
int merge(int p, int q){
	if(!p || !q)
		return p + q;
	tree[p].lis = std::max(tree[p].lis, tree[q].lis);
	tree[p].lds = std::max(tree[p].lds, tree[q].lds);
	// 最大上升子序列长度
	res = std::max(res, std::max(tree[tree[p].l].lis + tree[tree[q].r].lds,
		tree[tree[p].r].lds + tree[tree[q].l].lis));
	tree[p].l = merge(tree[p].l, tree[q].l);
	tree[p].r = merge(tree[p].r, tree[q].r);
	return p;
}
pii query(int p, int l, int r, int L, int R){ // L R 询问
	if(!p || l > r)
		return {0, 0};
	if(L <= l && r <= R)
		return {tree[p].lis, tree[p].lds};
	int m = (l + r) >> 1;
	pii ret = {-INF, -INF};
	pii tr, tl;
	if(L <= m)
		tl = query(tree[p].l, l, m, L, R);
	if(m < R)
		tr = query(tree[p].r, m+1, r, L, R);
	ret.first = std::max(tl.first, tr.first);
	ret.second = std::max(tl.second, tr.second);
	return ret;
}
void dfs(int u, int f){
	rt[u] = 0;
	for(int i = head[u]; ~i; i = e[i].next){
		int v = e[i].to;
		if(v == f)
			continue;
		dfs(v, u);
	}
	int nlis = 0, nlds = 0;
	for(int i = head[u]; ~i; i = e[i].next){
		int v = e[i].to;
		if(v == f)
			continue;
		int lis = query(rt[v], 1, n, 1, val[u]-1).first;
		int lds = query(rt[v], 1, n, val[u]+1, n).second;
		rt[u] = merge(rt[u], rt[v]);
		res = std::max(res, lis + 1 + nlds);
		res = std::max(res, nlis + 1 + lds);
		nlis = std::max(nlis, lis);
		nlds = std::max(nlds, lds);
	}
	update(rt[u], 1, n, val[u], nlis + 1, nlds + 1);
}
void calc(int S, int u){
	maxPart = S;
	getrt(S, u, 0);
	vis[root] = 1;
	int maxx = 0, pos = -1;
	for(int i = head[root]; ~i; i = e[i].next){
		int v = e[i].to;
		res = 0;
		dfs(v, root);
		if(res > maxx){
			maxx = res;
			pos = v;
		}
	}
	ans = std::min(ans, maxx);
	if(pos == -1 || vis[pos])
		return ;
	calc(sz[pos], pos);
}
void solve(){
	std::cin >> n;
	init();
	for(int i = 1; i < n; i++){
		int u, v;
		std::cin >> u >> v;
		add(u, v);
		add(v, u);
	}
	for(int i = 1; i <= n; i++)
		std::cin >> val[i];
	ans = INF;
	calc(n, 1);
	std::cout << ans << '\n';
}

int main(){
	std::cin.tie(nullptr)->sync_with_stdio(false);
	
    int T;
    // std::cin >> T;
    T = 1;
    while(T--){
        solve();
    }

	return 0;
}

 

 

 


http://www.kler.cn/a/388955.html

相关文章:

  • Microsoft 365 Exchange如何设置可信发件IP白名单
  • C#文字识别API场景解析、表格识别提取
  • JSON-RPC-CXX深度解析:C++中的远程调用利器
  • 深入理解BERT模型配置:BertConfig类详解
  • Android Framework AMS(16)进程管理
  • [代码随想录Day10打卡] 理论基础 232.用栈实现队列 225. 用队列实现栈 20. 有效的括号 1047. 删除字符串中的所有相邻重复项
  • WAL日志
  • 逐行加载 HTML 内容并实时显示效果:使用 wxPython 的实现
  • c++中的变量与常量
  • 绿色未来的关键:先进氢气压力容器技术取得重大进展
  • PHP API为什么要使用多种提交方式
  • Linux的基本指令(一)
  • 数仓工具—Hive语法之窗口函数中的order by
  • mybatisgenerator生成mapper时报错
  • Chapter1:python数据结构与算法
  • 解耦与模块化:鸿蒙平台上的服务注册与查找机制
  • 【Ubuntu】ubuntu 22.04 设置 Xorg 弃用 Wayland
  • webstorm 设置总结
  • Excel和微软小冰的结合应用
  • 7天用Go从零实现分布式缓存GeeCache(学习)(2)
  • MATLAB双坐标轴的figure图中第2个坐标轴怎么调整大小?
  • 数据结构 ——— 查找链式二叉树中值为X的节点
  • RabbitMQ的DLX(Dead-Letter-Exchange 死信交换机,死信交换器,死信邮箱)(重要)
  • OpenCV通过指针裁剪图像
  • C#绑定窗口句柄,获取后台窗口的图片的实现与分析
  • 聚观早报 | 荣耀Magic7 Pro开售;零跑汽车公布10月销量