2019.06.06 【NOIP提高组】模拟 A 组 模拟+指针+bfs

21 篇文章 0 订阅
14 篇文章 0 订阅

0 求导

在这里插入图片描述
求导的意思:

多项式是由若干个单项式构成的

单项式的一般形式是ax^b,其中ab都是常数,x是自变量

对于单项式axb求导,结果就是(ab)x(b-1)
对于多项式求导,就是把构成它的所有单项式分别求导之后相加

特别地,对于ax^0,即对常数a求导,结果是0

大模拟

#include <cstdio>

using namespace std;

long long a,b;
int i=0,flag=1,k=0;

int main(){
	freopen("equation.in","r",stdin);
	freopen("equation.out","w",stdout);
	char ch=getchar();
	while ((ch!='-')&&(ch!='x')&&(ch<'0'||ch>'9')) ch=getchar();
	while (1){
		a=0,b=0;
		if (ch=='-') flag=-1,ch=getchar();
		if (ch=='x'){
			a=1;
		}else
		while (ch>='0'&&ch<='9'){
			a=a*10+ch-'0';
			ch=getchar();
		}
		if (ch=='x'){
			ch=getchar();
			if (ch=='^'){
				ch=getchar();
				while (ch>='0'&&ch<='9'){
					b=b*10+ch-'0';
					ch=getchar();
				}
			}else  b=1;
		}
		if (b>=1){
			k++;
			if (k>1)
				if (flag==1) printf("+");
						else printf("-");
			else if (flag==-1)  printf("-");
			printf("%lld",a*b);
			if (b>1) printf("x");
			if (b>2) printf("^%lld",b-1);
		}
		if (ch=='-') flag=-1;else flag=1;
		if ((ch!='+')&&(ch!='-')) break;
		ch=getchar();
	}
	if (k==0) printf("0");
}

1 成绩调研

在这里插入图片描述

学号连续的学生!
那么维护两个尾指针,一个指向最早的满足条件的学生,一个指向最后的满足条件的学生,一个头指针逐次递增
用末位置减初位置得当前头指针可取得所有可能样本数,答案累加

#include <cstdio>
#include <cstring>

using namespace std;

int a[200005],s1[200005],s2[200005];
int n,k,h,t1,t2,cnt;
long long ans;
int l[200005],r[200005];

int main(){
	freopen("survey.in","r",stdin);
	freopen("survey.out","w",stdout);
	scanf("%d%d",&n,&k);
	cnt=k;
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for (int i=1;i<=k;i++){
		scanf("%d%d",&l[i],&r[i]);
		if (l[i]==0) cnt--;
	}
	t1=t2=1;
	for (int i=1;i<=n;i++){
		while (t1<i) t1++;
		while (t2<i) t2++;
		if (i!=1){
			if (s1[a[i-1]]==l[a[i-1]]) cnt++;
			s1[a[i-1]]--;s2[a[i-1]]--;
		}
		while (t1<=n&&cnt>0){
			s1[a[t1]]++;
			if (s1[a[t1]]==l[a[t1]]) cnt--;
			t1++;
		}
		while (t2<=n&&s2[a[t2]]<r[a[t2]]){
			s2[a[t2]]++;
			t2++;
		}
		if (t1<=t2&&cnt==0){
			ans+=(long long)t2-t1+1;
		}
	}
	printf("%lld",ans);
}

2 跟踪

在这里插入图片描述

有点像树形dp,但是其实用bfs就可以
可以把石神被追上,看成陌生人和石神同时或更早到达某个点
求出两个陌生人和石神到每个点的最早时间,然后找到最迟被追上的点求时间

#include <cstdio> 
#include <cstring>
#include <algorithm>

using namespace std;

const int N=200005;
int n,s,p,q,ans;
int tot,ls[N],ne[N*2],y[N*2];
int d[N][5],b[N];
int v[N];

void set(int u,int v){
	ne[++tot]=ls[u];ls[u]=tot;y[tot]=v;
	ne[++tot]=ls[v];ls[v]=tot;y[tot]=u;
}

void dfs(int x,int c){
	for (int i=ls[x];i;i=ne[i])
	if (b[y[i]]==0){
		b[y[i]]=1;
		if (c==1) 
			if (x!=s) d[y[i]][c]=d[x][c]+3; 
				 else d[y[i]][c]=d[x][c]+1;
		else{
			if (d[x][c]%3==0) d[y[i]][c]=d[x][c]+2;
						 else d[y[i]][c]=d[x][c]+1;
		}
		dfs(y[i],c);
	}
}

void bfs(){
	int h=0,t=1;
	b[s]=1;v[t]=s;
	while (h<t){
		int x=v[++h];
		ans=max(ans,min(d[x][2],d[x][3]));
		if (d[x][1]+2<d[x][2]&&d[x][1]+2<d[x][3])
		for (int i=ls[x];i;i=ne[i])
		if (b[y[i]]==0){
			v[++t]=y[i];
			b[y[i]]=1;
		}
	}
}

int main(){
	freopen("track.in","r",stdin);
	freopen("track.out","w",stdout);
	scanf("%d%d%d%d",&n,&s,&p,&q);
	for (int i=1;i<n;i++){
		int xi,yi;
		scanf("%d%d",&xi,&yi);
		set(xi,yi);
	}
	memset(b,0,sizeof b);
	b[s]=1;dfs(s,1);
	memset(b,0,sizeof b);
	b[p]=1;dfs(p,2);
	memset(b,0,sizeof b);
	b[q]=1;dfs(q,3);
	memset(b,0,sizeof b);
	bfs();
	printf("%d",ans);
}

他穿过昏君殿上美人层叠的舞袖,穿过小人朝中妒恨猜忌的谗语,穿过史官笔下冷厉无情的汗青,只为四海苍生驻足,只为九州黎民逗留。
——可他从没为他停过哪怕一次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值