7.18比赛补题报告

I. Running S

洛谷 P1353 [USACO08JAN] Running S

题意

给定2个整数 n n m m 分别代表运动的总时间和奶牛所能承受的疲劳度,接下来是 n n 个数字,均代表奶牛在第下标分钟内所能移动的距离,奶牛在每分钟内有两种选择:1、运动,但会增加单位一的疲劳度 2、休息,会减少单位一的疲劳度,但是一旦开始休息,就必须休息至疲劳度减为0。
现在要使这个奶牛在疲劳度在整个过程中不会超过其所能承受范围( m m )的情况之下移动的距离最远,求解这个最远的距离。

思路

这道题十分显然是一个动态规划, d p dp dp 数组会受到两个重要的因素的影响:当前的时间和当前的疲劳度,所以说 d p dp dp 数组应该是一个二维数组,两个因素分别占一个下标, d p i , j dp_{i,j} dpi,j 内存储的是在第 i i i 分钟时疲劳度为 j j j 的最远距离。
由第一种情况是运动,由于每次运动增加一单位的疲劳度,并且一次运动是在一分钟内的,所以可以很容易地得出 d p i , j =   m a x (   d p i , j ,   d p i − 1 , j − 1 + a i   ) dp_{i,j} = ~max(~dp_{i,j},~dp_{i-1,j-1}+a_i~) dpi,j= max( dpi,j, dpi1,j1+ai )
第二种情况是休息,由于休息后必须将疲劳度降回0,我们遍历求值中数组的 j j j 就应该是0,那么当前的时间与我们需要查询的上一个位置的时间之差就应该是上一个位置的疲劳度,即 d p i , j = m a x (   d p i , j ,   d p i − k , k   )   ( j = 0 , k ≤ m i n ( i , m ) ) dp_{i,j}=max(~dp_{i,j},~dp_{i-k,k}~)~(j=0,k\leq min(i,m)) dpi,j=max( dpi,j, dpik,k ) (j=0,kmin(i,m))

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,a[10005],dp[10005][505];
int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++){
		dp[i][0]=max(dp[i][0],dp[i-1][0]);
		for(int j=1;j<=min(i,m);j++){
			dp[i][j]=max(dp[i-1][j-1]+a[i],dp[i][j]);
			dp[i][0]=max(dp[i][0],dp[i-j][j]);
		}
	}
	printf("%d",dp[n][0]);
	return 0;
}

II. 波浪数

洛谷 P1112 波浪数

题意

给定五个数: l , r , L , R , k   l,r,L,R,k~ l,r,L,R,k 要求在 [ l , r ] [l,r] [l,r]进制内找到十进制下 [ L , R ] [L,R] [L,R]范围内在 k k k 个进制下都符合数字构成为两个数字交替反复出现的数,在十进制下从小的到大输出。

思路

这道题就是需要我们模拟构造这样的数,首先我们要在最外侧枚举进制从 l l l r r r,然后进行双层循环模拟组成要求的数字的每一位,每一个数字都不能超过当前进制数,首位不能为前导零,因此第一个数字从1开始枚举,并且枚举的这两个数字一定不能相同。在枚举出进制和所组成的两个数字之后就需要构造出十进制下的这个数,这里使用一个while循环逐位构造,然后我们需要一个桶数组来记录这个数满足在多少种进制下符合要求,当这个构造出的数满足在 [ L , R ] [L,R] [L,R] 范围内时,需要在桶数组中将它的出现次数加一,在最后,我们需要从小到大把 [ L , R ] [L,R] [L,R] 范围内所有数都遍历一遍桶,输出满足出现次数与 k k k 相等的数。

代码

#include<bits/stdc++.h>
using namespace std;
int a,b,l,r,x;
int mp[10000005];
int main(){
	scanf("%d %d %d %d %d",&a,&b,&l,&r,&x);
	for(int i=a;i<=b;i++){
		for(int j=1;j<i;j++){
			for(int k=0;k<i;k++){
				if(k==j){
					continue;
				}
				int w=0,cnt=0;
				while(cnt<=r){
					if(w%2==1){
						cnt=j+i*cnt;
					}
					else{
						cnt=k+i*cnt;
					}
					w++;
					if(cnt>=l&&cnt<=r){
						++mp[cnt];
					}
				}
				
			}
		}
	}
	for(int i=l;i<=r;i++){
		if(mp[i]==x){
			printf("%d\n",i);
		}
	}
	return 0;
}

III. 无序字母对

题意

给定 n n n 个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有 ( n + 1 ) ( n + 1 ) (n+1)(n+1) (n+1)(n+1) 个字母的字符串使得每个字母对都在这个字符串中出现。

思路

实际上,这道题真正的题意就是求出给定无向图的字典序最小的欧拉路径/回路。首先是建图,这道题由于点的都是字母共 26 × 2 = 52 26\times2=52 26×2=52 个,数据可谓非常之小,直接使用邻接矩阵建,然后利用并查集判断此图是否为连通图,如不是,直接 N o   S o l u t i o n No~Solution No Solution,然后判断无向图是否存在欧拉路径/回路,否则 N o   S o l u t i o n No~Solution No Solution,若存在欧拉路径,以奇点为起点dfs,若存在欧拉回路,以字典序最小之点为起点dfs。

代码

#include<bits/stdc++.h>
using namespace std;
int n;
int mp[150][150];
string s;
int f[150],dep[150];
char ans[1500];
int Find(int x){
	if(x==f[x]){
		return x;
	}
	return f[x]=Find(f[x]);
}
void dfs(int x){
	for(int i=60;i<=150;i++){
		if(mp[x][i]){
			mp[x][i]=mp[i][x]=0;
			dfs(i);
		}
	}
	ans[n--]=x;
}
int main(){
	scanf("%d",&n);
	for(int i=60;i<150;i++){
		f[i]=i;
	}
	for(int i=1;i<=n;i++){
		cin>>s;
		mp[s[0]][s[1]]++;
		mp[s[1]][s[0]]++;
		int xx=Find(s[0]);
		int yy=Find(s[1]);
		f[xx]=yy;
		dep[s[0]]++;
		dep[s[1]]++;
	}
	int flag=0;
	for(int i=60;i<150;i++){
		if(dep[i]&&f[i]==i){
			flag++;
		}
	}
	if(flag!=1){
		printf("No Solution");
		return 0;
	}
	flag=0;
	int p=0;
	for(int i=60;i<=150;i++){
		if(dep[i]&1){
			flag++;
			if(p==0){
				p=i;
			}
		}
	} 
	if(flag&&flag!=2){
		printf("No Solution\n");
		return 0;
	}
	if(p==0){
		for(int i=60;i<=150;i++){
			if(dep[i]){
				p=i;
				break;
			}
		}
	}
	dfs(p);
	printf("%s",ans);
	return 0;
}

IV. Points

洛谷 CF19D Points
Codeforces Points

题意

给定 n n n 次操作,每次操作有3种形式:
1、add x y添加点 ( x , y ) (x,y) (x,y)
2、remove x y删除点 ( x , y ) (x,y) (x,y)
3、find x y寻找在点 ( x , y ) (x,y) (x,y)右上方的点,若没有,输出 − 1 -1 1 ,若有多个,找到最左边的点中最下面的点

代码

#include <bits/stdc++.h>
using namespace std;
#define LL long long

const LL mod = 1e9 + 7;
const int N = 2e5 + 50;

int n;
vector<int> xl, yl;
string op;
struct qu {
    int op, x, y;
} Q[N];
set<int> s[N];

struct node {
    int l, r, v;
} T[N << 2];

void build(int rt, int l, int r) {
    T[rt].l = l, T[rt].r = r;
    if (l == r) {
        return;
    }
    int mid = (l + r) >> 1;
    build(rt << 1, l, mid);
    build(rt << 1 | 1, mid + 1, r);
}

void update(int rt, int x, int v) {
    if (T[rt].l == T[rt].r) {
        T[rt].v = v;
        return;
    }
    int mid = (T[rt].l + T[rt].r) >> 1;
    if (x <= mid) {
        update(rt << 1, x, v);
    } else {
        update(rt << 1 | 1, x, v);
    }
    T[rt].v = max(T[rt << 1].v, T[rt << 1 | 1].v);
}

int query(int rt, int x, int y) {
    if (T[rt].l == T[rt].r) {
        if (T[rt].v > y) {
            return T[rt].l;
        }
        return -1;
    }
    int mid = (T[rt].l + T[rt].r) >> 1, res = -1;
    // 找到大于x,y且最小的值
    if (x <= mid && T[rt << 1].v > y) {
        res = query(rt << 1, x, y);
    }
    if (~res) {
        return res;
    }
    if (T[rt << 1 | 1].v > y) {
        return query(rt << 1 | 1, x, y);
    }
    return -1;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        int xt, yt;
        cin >> op >> xt >> yt;
        xl.push_back(xt);
        yl.push_back(yt);
        if (op == "add") {
            Q[i] = {1, xt, yt};
        } else if (op == "remove") {
            Q[i] = {2, xt, yt};
        } else {
            Q[i] = {3, xt, yt};
        }
    }
    sort(xl.begin(), xl.end());
    sort(yl.begin(), yl.end());
    // unique有序序列去重 ,返回最后一个不重复的数字在序列中的位置
    xl.erase(unique(xl.begin(), xl.end()), xl.end());
    yl.erase(unique(yl.begin(), yl.end()), yl.end());
    for (int i = 1; i <= n; ++i) {
        Q[i].x = lower_bound(xl.begin(), xl.end(), Q[i].x) - xl.begin() + 1;
        Q[i].y = lower_bound(yl.begin(), yl.end(), Q[i].y) - yl.begin() + 1;
    }
    build(1, 1, N - 1);
    for (int i = 1; i <= n; ++i) {
        if (Q[i].op == 1) {
            // 使用线段树维护x坐标上面最大的y坐标
            // 对应的x坐标的set中,存储了当前x坐标对应的所有y坐标
            s[Q[i].x].insert(Q[i].y);
            int p = *s[Q[i].x].rbegin();

            update(1, Q[i].x, p);
        } else if (Q[i].op == 2) {
            // 集合中应该删除当前这个点的y坐标
            s[Q[i].x].erase(Q[i].y);
            int p;
            if (s[Q[i].x].size() == 0) {
                p = 0;
            } else {
                // 获取一个新的最大值
                p = *s[Q[i].x].rbegin();
            }
            update(1, Q[i].x, p);
        } else {
            int p = query(1, Q[i].x + 1, Q[i].y);
            if (p == -1) {
                cout << p << endl;
            } else {
                int py = *s[p].upper_bound(Q[i].y);
                cout << xl[p - 1] << ' ' << yl[py - 1] << endl;
            }
        }
    }
    return 0;
}
内容概要:本研究聚焦于绿电直连型电氢氨园区的优化运行,提出一种集成绿色电力直接供给、电解水制氢及氢气合成氨工艺的综合能源系统架构。通过建立包含风光发电、电解槽、氨合成反应器、储氢罐、电网交互及多类型负荷在内的系统模型,综合考虑绿电直供优先、能量梯级利用与多能互补原则,构建以系统综合运行成本最小化为目标的优化调度模型。研究采用Matlab与Python工具进行算法求解和仿真分析,利用实际气象与负荷数据完成案例验证,评估了不同运行策略下系统的经济性、可再生能源消纳能力与碳减排效益,为新型电氢氨一体化园区的规划与运行提供了理论依据和技术支撑。; 适合人群:具备一定电力系统、新能源或化工背景的研究生、科研人员及从事综合能源系统规划与优化工作的工程技术人员。; 使用场景及目标:①用于科研学习,理解电-氢-氨多能转换系统的建模与优化方法;②为工业园区的低碳化、智能化改造提供技术参考与决策支持;③作为开发类似综合能源管理系统的理论基础。; 阅读建议:此资源包含完整的模型代码、数据与论文,使用者应结合代码仔细研读论文中的模型构建部分,重点关注目标函数与约束条件的设计逻辑,并尝试修改参数进行仿真,以深入掌握优化算法在实际系统中的应用。
内容概要:本文深入探讨了RS485通信协议在芯片行业自动化测试系统中的实际开发与应用,涵盖其关键概念、电气特性、通信机制及与Modbus RTU协议的结合使用。文章重点介绍了差分信号完整性设计、主从时序控制、CRC校验与重传机制等核心技术要点,并通过一个基于Python的完整代码实例,展示了如何实现RS485主站对探针台、自动分选机等芯片测试设备的控制与数据采集。此外,还分析了RS485在晶圆探针台、ATE设备集群和环境监控等典型场景的应用,并展望了其与工业以太网融合、智能化诊断、高速化及AI集成的发展趋势。; 适合人群:具备一定嵌入式系统或工业通信基础,从事芯片测试、自动化设备开发及相关领域的研发人员,尤其是工作1-3年希望提升现场总线应用能力的工程师。; 使用场景及目标:①理解RS485在高干扰芯片测试环境中稳定通信的设计原理;②掌握Modbus RTU协议在Python下的实现方法,用于实际控制探针台、Handler等设备;③构建可靠的数据采集与设备控制系统,支持CRC校验、异常处理和日志追踪;④为后续向高速通信和智能诊断系统升级提供技术储备。; 阅读建议:此资源强调实战开发,建议结合硬件环境动手调试代码,重点关注线程锁、CRC计算、帧解析和超时控制等关键环节,在真实产线中验证通信稳定性,并利用日志系统进行故障分析与优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值