【考题题解6】稍复杂的模拟 栈+dfs 单调队列

本文解析了四道编程题目,包括模拟游戏中的生存者、食堂座位安排、括号表达式的值计算以及解决旅行中的加油问题。通过具体算法和代码实现,展示了如何运用数据结构和算法解决问题。

1.无聊的游戏

由题意可得,这道题只需要村模拟即可,就是稍微复杂里一点

1.循环枚举每一个没死的同学,找到与该同学最近的一个非自身且没有死的同学,然后将其杀掉(标记一下)即可。

2.因为给的同学的位置是坐标系的坐标,所以求最近距离是要用上勾股定理,即行列的绝对值之差的平方之和。

3.如果一次循环没有把剩下的杀死,那就再循环一次即可。

4.如果在模拟的过程中总数为1,那么就找到唯一生存的同学并且输出以及退出循环。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int students;
struct Cristiano_Ronaldo
{
	int x,y,die;
}student[3000]={};//x,y记录坐标;die记录该学生是否死掉
inline int find_the_shortest_student(int student_number)//找到与第student_number个学生最近的学生
{
	double shortest_distance=999999999.0;
	int shortest_student_number=0;
	for (int i=1;i<=students;i++)
	    if (i!=student_number&&student[i].die==0)//学过没有死并且不是自己本身
	    {
	    	double distance=sqrt(pow(abs(student[student_number].x-student[i].x),2)
			                  +pow(abs(student[student_number].y-student[i].y),2));
			if (shortest_distance>distance)
			{
				shortest_distance=distance;
				shortest_student_number=i;
			}//勾股定理求最小值
	    }
	return shortest_student_number;
}
inline int find_the_only_one_student()//找到唯一生存的学生
{
	for (int i=1;i<=students;i++)
	if (student[i].die==0) return i;
}
int main()
{
	cin>>students;
	if (students==0) 
	{
		cout<<0;
		return 0;
	}
	for (int i=1;i<=students;i++)
	    cin>>student[i].x>>student[i].y;
	for (int i=1;i<=3000;i++) 
	    student[i].die=0;//标记未死亡
	int sum=students;
	while (true)
	{
		for (int i=1;i<=students;i++)
		{
			if (sum==1)//如果只剩下一个学生
			{
				cout<<find_the_only_one_student();
				return 0;
			}
			if (sum>1&&student[i].die==0)//如果该学生没死并且总数大于1
			{
				int willdie=find_the_shortest_student(i);//找到最近的学生
				student[willdie].die=1;//杀死
				sum--;
			}
		}
		if (sum==1)
		{
			cout<<find_the_only_one_student();//找到唯一生存的学生
			return 0;
		}
	}
	return 0;
}

2.食堂的座位

模拟条件:

1.如果该座位是单人的,那么优先考虑左半部分,避免对后面产生影响,如果没有再考虑右边

2.如果是双人座位的左边,那么就判断左边有没有位置;如果是双人座位的右边,那么就判断座位的右边有没有位置。

3.因为数据较少,用二维数组uesd[i][j]来表示i和j之间的位置是否被坐。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int seats,used[100][100]={},double_seat=-1,ans=0;
	char seat[1000]={};
	cin>>seats;
	for (int i=1;i<=seats;i++) 
	    cin>>seat[i];
	for (int i=1;i<=seats;i++)
	{
		if (seat[i]=='S') 
		{
			if (used[i-1][i]==0) used[i-1][i]=1;
			    else if (used[i][i+1]==0) used[i][i+1]=1;
			        else ans++;
		}//判断是单人座位的情况
		if (seat[i]=='L')
		{
			double_seat=(double_seat+1)%2;//该变量控制的是双人座位的方向,即左边或右边
	    	if (double_seat==0) 
     		    if (used[i-1][i]==0) used[i-1][i]=1;
    		       else ans++;
    		else
	    	    if (used[i][i+1]==0) used[i][i+1]=1;
	    	        else ans++;
	    }//判断双人座位的情况
	}
	cout<<seats-ans;
	return 0;
}

3.括号表达式的值

1.因为由题意可得,括号是平衡的,因此可以用括号匹配来做,找出与每一个左括号所匹配的右括号。

2.括号匹配的方法如下:用栈记录左括号的地址,每次匹配到一个右括号就记录栈顶所匹配的右括号的地址,并出栈,如此反复操作即可。

3.接着,就可以dfs了,先dfs(1,n),然后接着递归就可以。

递归过程如下:

a.如果它由多个平衡的括号组成,就递归第一个平衡的括号和剩下部分。

b.如果有且只有一对不嵌套的括号,返回值为2.

c.如果只有一对平衡且带有嵌套的括号,去掉头和尾接着递归,并且结果乘2即可。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const long long Mod=12345678910;
struct Cristiano_Ronaldo
{
	int num,next;//num记录0和1,next记录匹配的右括号
}a[100000]={};
long long dfs(long long l,long long r)//dfs递归
{
	long long ans=0;
	if (a[l].next<r) ans=(ans+((dfs(l,a[l].next)%Mod)+(dfs(a[l].next+1,r)%Mod)%Mod))%Mod;//上述条件a
	if (l+1==r) ans=(ans+1)%Mod;//上述条件b
	if (a[l].next==r&&l+1<r) ans=(ans+2*(dfs(l+1,r-1)%Mod)%Mod)%Mod;//上述条件c
	return ans;
}
int main()
{
	long long n,top=0,st[100000]={};
	cin>>n;
	for (int i=1;i<=n;i++)cin>>a[i].num;
	for (int i=1;i<=n;i++)
	{
		if (a[i].num==1) a[st[top]].next=i,top--;
		if (a[i].num==0) st[++top]=i;
	}//进行括号匹配
	cout<<dfs(1,n);
	return 0;
}

4.加油问题

1.因为数据没有排序,应按照地点进行排序。

2.排序后,要使加油费最小,用单调队列来维护每一个加油站的加油费和每一个加油站作加的油,令最便宜的油在对头即可。

3.因为要使车能达到终点,没到一个站都要把油加满,如果加的油比队尾的油要便宜,那么就把队尾去掉,直到前面的油比它大或者队列为空即可。

4.每次要用油的时候就从对头取油用,因为是最便宜的。

5.因为一开始已经拥有的油是不用钱的,说宜价格标记为0即可。

Q:这么反复将油加满不会对结果产生影响吗?因为加了很多没必要的油啊,那么结果不是会更高吗?

A:不会,因为队列只是用来控制可用的且最便宜的油的数量,最后用多少要看你在对头去多少油,因此给加满油的油不一定会用完,而是取多少用多少,最终的结果也只是和你取得油量有关。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int head=1,tail=1,ans=0;
struct jgt
{
	int x,y;
}a[100000]={};
bool cmp(jgt xx,jgt yy)
{
	return (xx.x<yy.x);
}
struct que
{
	int p,h;//p=price,h=have
}q[100000]={}; 
void go(int x)
{
	int s=x;
	while (true)
	{
		if (s<q[head].h)//如果距离小于存油量 
		{
			q[head].h-=s;//减少存油量 
			ans+=q[head].p*s;// 将用去的油乘这个油的价格存入总花费 
			return;
		}
		else//如果大于存油量 
		{
			s-=q[head].h;//当该油量用完时 总路程也减少 
			ans+=q[head].p*q[head].h;//算花费 
			head++;//去对头 
		}
	}
} 
int pre_sum(int h,int t)//查找h到t区间的油量之和 
{
	int sum=0;
	for (int i=h;i<=t;i++)
	    sum+=q[i].h;
	return sum;
}
int main()
{
	int n,g,b,d;
	cin>>n>>g>>b>>d;
	for (int i=1;i<=n;i++)
	    cin>>a[i].x>>a[i].y;
	sort(a+1,a+n+1,cmp); //按照地点排序 
	q[1].p=0;
	q[1].h=b;//把原有油进队 
	for (int i=1;i<=n;i++)
	{
		if (g<a[i].x-a[i-1].x)//如果两点间的距离比所能存储的容量大的话无解 
		{
			cout<<-1;
			return 0;
		}
		go(a[i].x-a[i-1].x);//走到下一个点,括号内表示走的距离 
		while (a[i].y<q[tail].p&&head<=tail) 
		    tail--;//如果要新加入的元素的价格比队尾要小,切队列不为空 
		q[++tail].p=a[i].y;//储存价格 
		q[tail].h=g-pre_sum(head,tail-1);//储存所能存储的油量 
	}
	if (g<d-a[n].x)
	    cout<<-1;
    else
        go(d-a[n].x);//从最后一个点走到终点 
	cout<<ans;
	return 0;
} 

内容概要:本文设计了一种基于PLC的全自动洗衣机控制系统内容概要:本文设计了一种,采用三菱FX基于PLC的全自动洗衣机控制系统,采用3U-32MT型PLC作为三菱FX3U核心控制器,替代传统继-32MT电器控制方式,提升了型PLC作为系统的稳定性与自动化核心控制器,替代水平。系统具备传统继电器控制方式高/低水,实现洗衣机工作位选择、柔和过程的自动化控制/标准洗衣模式切换。系统具备高、暂停加衣、低水位选择、手动脱水及和柔和、标准两种蜂鸣提示等功能洗衣模式,支持,通过GX Works2软件编写梯形图程序,实现进洗衣过程中暂停添加水、洗涤、排水衣物,并增加了手动脱水功能和、脱水等工序蜂鸣器提示的自动循环控制功能,提升了使用的,并引入MCGS组便捷性与灵活性态软件实现人机交互界面监控。控制系统通过GX。硬件设计包括 Works2软件进行主电路、PLC接梯形图编程线与关键元,完成了启动、进水器件选型,软件、正反转洗涤部分完成I/O分配、排水、脱、逻辑流程规划水等工序的逻辑及各功能模块梯设计,并实现了大形图编程。循环与小循环的嵌; 适合人群:自动化套控制流程。此外、电气工程及相关,还利用MCGS组态软件构建专业本科学生,具备PL了人机交互C基础知识和梯界面,实现对洗衣机形图编程能力的运行状态的监控与操作。整体设计涵盖了初级工程技术人员。硬件选型、; 使用场景及目标:I/O分配、电路接线、程序逻辑设计及组①掌握PLC在态监控等多个方面家电自动化控制中的应用方法;②学习,体现了PLC在工业自动化控制中的高效全自动洗衣机控制系统的性与可靠性。;软硬件设计流程 适合人群:电气;③实践工程、自动化及相关MCGS组态软件与PLC的专业的本科生、初级通信与联调工程技术人员以及从事;④完成PLC控制系统开发毕业设计或工业的学习者;具备控制类项目开发参考一定PLC基础知识。; 阅读和梯形图建议:建议结合三菱编程能力的人员GX Works2仿真更为适宜。; 使用场景及目标:①应用于环境与MCGS组态平台进行程序高校毕业设计或调试与运行验证课程项目,帮助学生掌握PLC控制系统的设计,重点关注I/O分配逻辑、梯形图与实现方法;②为工业自动化领域互锁机制及循环控制结构的设计中类似家电控制系统的开发提供参考方案;③思路,深入理解PL通过实际案例理解C在实际工程项目PLC在电机中的应用全过程。控制、时间循环、互锁保护、手动干预等方面的应用逻辑。; 阅读建议:建议结合三菱GX Works2编程软件和MCGS组态软件同步实践,重点理解梯形图程序中各环节的时序逻辑与互锁机制,关注I/O分配与硬件接线的对应关系,并尝试在仿真环境中调试程序以加深对全自动洗衣机控制流程的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值