作业5、6+模拟

本文介绍了编程作业中的多个算法问题,包括最大矩形面积计算、数组区间修改、平衡字符串和滑动窗口问题。针对每个问题,文章提供了思路解析和代码实现。此外,还涉及到了网络问题,如寻找网络中电脑的最大距离,以及防疫相关的群体隔离算法。文章强调了课堂知识的重要性,以及在解决问题时避免超时和提高代码效率的策略。
摘要由CSDN通过智能技术生成

作业Week5
A-最大矩形
1.题意:给一个直方图,求直方图中的最大矩形的面积。例如,下面这个图片中直方图的高度从左到右分别是2, 1, 4, 5, 1, 3, 3, 他们的宽都是1,其中最大的矩形是阴影部分。
在这里插入图片描述
Input:
输入包含多组数据。每组数据用一个整数n来表示直方图中小矩形的个数,你可以假定1 <= n <= 100000. 然后接下来n个整数h1, …, hn, 满足 0 <= hi <= 1000000000. 这些数字表示直方图中从左到右每个小矩形的高度,每个小矩形的宽度为1。 测试数据以0结尾。

Output:
对于每组测试数据输出一行一个整数表示答案。

2.思路:首先,我们注意到该题hi的范围是0~1000000000,所以数据类型应选用long long int,而不是int。要计算出矩形的最大面积,我们要计算出最大高度对应的最大宽度,由此可以计算出各个高度所对应的面积。我们可以用单调递增栈来计算出各高度对应的最大宽度,同时,栈内元素表示的是具体不同高度所对应的下标,故每当有元素出栈时,就可计算出栈顶元素对应高度的最大矩形面积,最后,再计算出各个面积的最大值便可得到答案。另,为了保证各高度均能从栈内弹出,可以向元素底加入一个0,从而确保。

3.代码:

#include <iostream>
#include <stack>
#include <cmath>
#include <algorithm>
using namespace std;

int main()
{
   
	int n;
	while(1)
	{
   
		cin>>n;
		if(n==0)
			return 0;
		long long int* a=new long long int[n+1];
		for(int i=0;i<n;i++)
			cin>>a[i];  a[n]=0;             
		stack<int> st;
		long long int area=0, b=0;
		int m=0;
		for(int i=0;i<=n;i++)
		{
   
			if(!st.empty()) m=st.top();
			while(!st.empty()&&a[i]<a[m])
			{
   
				m=st.top();
				st.pop();
				if(!st.empty())
					b=a[m]*(i-st.top()-1);	
				else
					b=a[m]*i;
				if(!st.empty())
					m=st.top() ;
				area=max(b,area);
			}
			st.push(i);
		}
		cout<<area<<endl;
	}
} 

B-TT’s Magic Cat
1.题意:现有一个长度为n的数组,现对其进行q次操作,每次操作给出L、R、c,表示区间【L,R】中的每个数均加上c,求q次操作后,区间中每个元素的值。
example:
input:
4 2 //数组中元素的个数和q
-3 6 8 4 //原数组
4 4 -2 //区间[4,4]中的元素每个数加上-2
3 3 1 //区间[3,3]中的每个元素加上1
output:
-3 6 9 2 //最终结果

2.思路:一开始把该题看得过于简单,使用了最笨的方法,挨个遍历,结果递交发现超时。为了避免超时,我们可以将原数组转换为差分数组,将区间修改转变为单点修改,即将a[L,R]=a[L,R]+c转换为b[L]=b[L]+c, b[R+1]=b[R+1]-c,b数组前缀和即为a数组最终数值,可通过a[i]=a[i-1]+b[i]计算出最终答案。
总结:课堂上讲到的每一个知识点都必定有它的用处,对于每一个点都要尽量去掌握,可以大大提高自己的代码效率。

3.代码:

#include <iostream>
#include <stdio.h>
using namespace std;

long long int a[1000000];
long long int b[1000000];
int main()
{
   
	int n,q;
	cin>>n>>q;
	a[0]=0;
	for(int i=1;i<=n;i++)
	{
   
		cin>>a[i];
		b[i]=a[i]-a[i-1];
	}
	for(int i=q;i>0;i--)
	{
   
		int l,r,c;
		cin>>l>>r>>c;
		b[l]=b[l]+c;
		b[r+1]=b[r+1]-c;
	}
	for(int i=1;i<=n;i++)
	{
   
		a[i]=b[i]+a[i-1];
		cout<<a[i]<<" ";
	}
	cout<<endl;		
}

C-平衡字符串
1.题意:一个长度为 n 的字符串 s,其中仅包含 ‘Q’, ‘W’, ‘E’, ‘R’ 四种字符。
如果四种字符在字符串中出现次数均为 n/4,则其为一个平衡字符串。
现可以将 s 中连续的一段子串替换成相同长度的只包含那四个字符的任意字符串,使其变为一个平衡字符串,问替换子串的最小长度?
如果 s 已经平衡则输出0。
example:
Input
QWER
Output
0

Input
QQWE
Output
1

Input
QQQW
Output
2

Input
QQQQ
Output
3

2.思路:本题使用尺取法。给定区间[L, R],用sum1、sum2、sum3、sum4四个数来计算不包含区间[L, R]这一段时,字符’Q’, ‘W’, ‘E’, 'R’的个数,通过替换使4类字符数量一致,再判断剩余空闲位置是否是4的倍数
MAX = max(sum1, sum2, sum3, sum4)
TOTAL = R – L + 1
BALANCE = TOTAL -[(MAX-sum1)+(MAX-sum2)+(MAX-sum3)+(MAX-sum4)]
如果BALANCE>=0且为4的倍数,则满足条件,反之不满足。根据尺取法,如果当前[L, R]满足要求,则L++;如果不满足要求,则R++。之后我们还要从前往后遍历整个数组即可得出最小的TOTAL。

3.代码:

#include<iostream>
#include<string.h>
#include<cmath>
using namespace std;

int a,b,c,d;
string s;

bool judge(int l,int r,int bal)
{
   
	int a1=0,b1=0,c1=0,d1=0;
	for(int i=l;i<=r&&bal!=0;i++)
	{
   
		if(s[i]=='Q')
			a1++;
		else if(s[i]=='W')
			b1++;
		else if(s[i]=='E')
			c1++;
		else if(s[i]=='R')
			d1++;
	}
	a1=a-a1,b1=b-b1,c1=c-c1, d1=d-d1;
	int Max=max(a1, b1);
	Max=max(Max, c1);
    Max=max(Max, d1);
    int tal=r-l+1;
	int sum=Max*4-a1-b1-c1-d1;
	int res=tal-sum;
	if(res<0||res%4!=0)
		return 0;
	else
		return 1;
}
int main()
{
   
	cin>>s;
	a=0,b=0,c=0,d=0;
	for(int i=0;i<s.length();i++)
	{
   
		if(s[i]=='Q')
			a++;
		else if(s[i]=='W')
			b++;
		else if(s[i]=='E')
			c++;
		else if(s[i]=='R')
			d++;
	}
	int l=0,r=0,balance=s.length();
	if(judge(0,0,0))
	{
   
		cout<<"0"<<endl;
		return 0;
	}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值