9.2 冲刺 NOIP2022 模拟赛 B 组 Day1 总结

T1 卡牌选取_xiyuping24的博客-CSDN博客

拆位拆串行挂50pts可还行qwq

T2互质数对

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=100010;
int n,m,res,a[N];
set<int> s;
int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int gcd(int x,int y){return y?gcd(y,x%y):x;}
signed main()
{
	freopen("pair.in","r",stdin);
	freopen("pair.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=n;++i) a[i]=read();
	for(int i=1;i<=m;++i)
	{
		int x=read();
		set<int>::iterator it;
		it=s.find(x);
		if(it==s.end())
		{
			for(auto t:s) if(gcd(a[x],a[t])==1) res++;
			s.insert(x);
		}
		else
		{
			s.erase(it);
			for(auto t:s) if(gcd(a[x],a[t])==1) res--;
		}
		printf("%d\n",res);
	}
	return 0;
}

T3 最小花费

 题中说航线有负权,但是道路是保证大于0的啊啊啊啊

这就说明不会有负环只会有负边权套SPFA就好 然而但是TLE挂了30分

考完查题解,发现有两个选择:1.缩点优化Dij 2.deque优化SPFA

deque优化我确实从来没见过(太菜辣)在spfa的基础上,在将当前点放入队列时,根据当前点是否比当前deque的队头更优,分别从队头放入和队尾放入即可,从而优化了维护队列中结点最优状态的时间复杂度。code:

#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
int n,r,p,s;
struct edge{int u,v,w,nxt;}e[N];
int head[N],tot,dis[N];
void addage(int u,int v,int w)
{
	e[++tot].u=u;
	e[tot].v=v;
	e[tot].w=w;
	e[tot].nxt=head[u];
	head[u]=tot;
}
bool vis[N];
void spfa(int x)
{
	memset(dis,0x3f,sizeof dis);
	vis[x]=1;dis[x]=0;
	deque<int>q;
	q.push_front(x);
	while(!q.empty())
	{
		int u=q.front();
		q.pop_front();
		vis[u]=0;
		for(int i=head[u]; i; i=e[i].nxt)
		{
			int v=e[i].v;
			if(dis[v]>dis[u]+e[i].w)
			{
				dis[v]=dis[u]+e[i].w;
				if(!vis[v])
				{
					if(q.empty()||dis[v]<dis[q.front()])
						q.push_front(v);
					else q.push_back(v);
					vis[v]=1;
				}
			}
		}
	}
}
int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	freopen("roadplane.in","r",stdin);
	freopen("roadplane.out","w",stdout); 
	n=read();r=read();
	p=read();s=read();
	for(int u,v,w,i=0; i<r; ++i)
	{
		u=read();
		v=read();
		w=read();
		addage(u,v,w);
		addage(v,u,w);
	}
	for(int u,v,w,i=0; i<p; ++i)
	{
		u=read();
		v=read();
		w=read();
		addage(u,v,w);
	}
	spfa(s);
	for(int i=1; i<=n; ++i)
		if(dis[i]==0x3f3f3f3f) puts("NO PATH");
		else printf("%d\n",dis[i]);
	return 0;
}

T4 公交运输

还是审题的锅:1.不支持换乘!!!   2.所有公交车从0出发!!!!

因为时间只剩30min所以很着急qwq,初始化一直有问题

正解需要斜率优化,但是50分还是比较容易的:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1000010;
int n,f[N],c[N],v[N],maxc; 
signed main()
{
	freopen("bus.in","r",stdin);
	freopen("bus.out","w",stdout);
	scanf("%lld%lld",&n,&maxc);
	for(int i=0;i<n;i++)
	{
		scanf("%lld%lld",&c[i],&v[i]);
		f[i]=1e12;
	}
	if(maxc==1)
	{
		int x=v[0],ans=0;
		for(int i=1;i<=n;i++)
		{
			ans+=x;
			x=min(x,v[i]);
			printf("%lld ",ans);
		}
		return 0;
	}
	f[n]=1e12,f[0]=0;
	for(int i=1;i<=n;i++)
	for(int j=i-1;j>=0;j--)
		if((i-j)%c[j]==0) f[i]=min(f[i],f[j]+(i-j)/c[j]*v[j]);
	for(int i=1;i<=n;i++)
	{
		if(f[i]==1e12) printf("-1 ");
		else printf("%lld ",f[i]);
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiyuping24

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值