Acwing第 55 场周赛【完结】

4479. 最长子序列【签到】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,t;
int a[N],b[N];
map<int,int>mp;
int main(void)
{ 

    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=m;i++) cin>>b[i],mp[b[i]]++;
    for(int i=1;i<=n;i++) if(mp[a[i]]) cout<<a[i]<<" ";
	return 0;
}

4480. 倒垃圾【前缀和】

在这里插入图片描述
挺常规的一道题,首先二分是可做的。这里我用的是前缀的思想。左右前缀取最近的。

#include<bits/stdc++.h> 
using namespace std;
const int N=1e5*2+10;
int a[N],st[N],cnt[N],n,m;
int l[N],r[N];
struct node{int x,id;}Node[N];
bool cmp(node a,node b){return a.x<b.x;}
int main(void)
{
	cin>>n>>m;
	for(int i=1;i<=n+m;i++) cin>>a[i];
	for(int i=1;i<=n+m;i++) cin>>st[i];
	for(int i=1;i<=n+m;i++) Node[i]={a[i],st[i]};
	sort(Node+1,Node+n+m+1,cmp);
	memset(l,0x3f,sizeof l);
	memset(r,0x3f,sizeof r);
	for(int i=1;i<=n+m;i++) 
	{
	    if(l[i-1]!=0x3f3f3f3f) l[i]=l[i-1];
	    if(Node[i].id) l[i]=i;
	}
	for(int i=n+m;i>=1;i--)
	{
	    if(r[i+1]!=0x3f3f3f3f) r[i]=r[i+1];
	    if(Node[i].id) r[i]=i;
	}
	for(int i=1;i<=n+m;i++)
	{
	    if(Node[i].id==0)
	    {
	        if(l[i]==0x3f3f3f3f) cnt[r[i]]++;
	        else if(r[i]==0x3f3f3f3f) cnt[l[i]]++;
	        else if(l[i]!=0x3f3f3f3f&&r[i]!=0x3f3f3f3f)
	        {
	            if(abs(Node[l[i]].x-Node[i].x)<=abs(Node[r[i]].x-Node[i].x)) cnt[l[i]]++;
	            else cnt[r[i]]++;
	        }
	    }
	}
	for(int i=1;i<=n+m;i++) if(Node[i].id) cout<<cnt[i]<<" ";
	return 0;
}

4481. 方格探索【思维 / 双端队列】

在这里插入图片描述
通过 终点纵坐标-起点纵坐标==右的步数-左的步数
我们设右边走的代价为1,来跑最短路。因为只有0/1边故可以用双端队列来搞。

#include<bits/stdc++.h> 
using namespace std;
typedef pair<int,int> PII;
const int N=2020;
int dist[N][N],st[N][N],n,m;
int stx,sty,cnt1,cnt2;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
char a[N][N];
void bfs(int x,int y)
{
    memset(dist,0x3f,sizeof dist);
	deque<PII>q; q.push_back({x,y});
	dist[x][y]=0;
	while(q.size())
	{
		auto temp=q.front(); q.pop_front();
		x=temp.first,y=temp.second;
		if(st[x][y]) continue;
		st[x][y]=1;
		for(int i=0;i<4;i++)
		{
			int tempx=x+dx[i];
			int tempy=y+dy[i];
			if(tempx<1 || tempx>n || tempy<1 || tempy>m) continue;
			if(a[tempx][tempy]=='*') continue;
			int w=0;
			if(i==1) w=1;
			if(dist[tempx][tempy]>dist[x][y]+w)
			{
			    dist[tempx][tempy]=dist[x][y]+w;
			    if(w) q.push_back({tempx,tempy});
			    else q.push_front({tempx,tempy});
			}
		}
	} 
}
int main(void)
{
	cin>>n>>m>>stx>>sty>>cnt1>>cnt2;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		    cin>>a[i][j];
	}
	bfs(stx,sty);
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			int temp1=dist[i][j];
			int temp2=temp1-(j-sty);
			if(temp1<=cnt2&&temp2<=cnt1) ans++;
		}
	}
	cout<<ans;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值