洛谷P1571题解()

我寻思着拿两个指针一扫不就得了?
首先把特殊贡献奖和科技创新奖排好序,再用指针寻找两个序列中编号相同的,最后输出。

时间复杂度大概为O(2*n*log(n)+2n)

因为排序打乱了原先科技创新奖获奖名单中的先后次序,所以我们要记录好每一个获得科技创新奖的人的编号的位置,并记录好原科技创新奖获奖名单中的先后次序.

直接输出排序后的编号只有20分
我的惨痛经历,调了30分钟

代码如下:

#include<algorithm>
#include<stdio.h>
#define MAXN 100005
using namespace std;
class node{
	public:
		int w,
			x;
}a[MAXN];//科技创新奖的人的编号,其中w是编号,x是位置
int n,m,b[MAXN],ai=1,bi=1,aa[MAXN],c[MAXN],k;
//b数组w为特殊贡献奖的人的位置,由于不需要先后顺序,直接用int型数组
//c数组存储了两个奖项都获得了的人的科技创新奖的位置,用于输出
//aa是原先科技创新奖获奖名单,用于输出
//ai,bi为a数组和b数组指针,k是用于记录c数组的指针
inline static bool cmp1(int x,int y){
	return x<y;
}
inline static bool cmp2(node x,node y){
	return x.w<y.w;
}
//都按升序排列
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i].w);
		aa[i]=a[i].w,a[i].x=i;
	}
	for(int i=1;i<=m;i++)scanf("%d",&b[i]);
//输入部分
	sort(a+1,a+n+1,cmp2);
	sort(b+1,b+m+1,cmp1);
//排序
	while(ai<=n and bi<=m){
		if(a[ai].w<b[bi])ai++;//当前ai所指的值比bi所指小,说明相等的编号在ai右侧,向右移
		if(a[ai].w>b[bi])bi++;//同理
		if(a[ai].w==b[bi]){//相等则记录
			c[++k]=a[ai].x;
			ai++,bi++;//跳过相等的值
		}
	}
	sort(c+1,c+k+1,cmp1);//对相等编号的位置排序,这样就是按照先后顺序的啦
	for(int i=1;i<=k;i++){
		printf("%d ",aa[c[i]]);//按原先后顺序输出编号
	}
	return (0^0);//结束撒花
}
————————

我寻思着拿两个指针一扫不就得了?
首先把特殊贡献奖和科技创新奖排好序,再用指针寻找两个序列中编号相同的,最后输出。

时间复杂度大概为O(2*n*log(n)+2n)

因为排序打乱了原先科技创新奖获奖名单中的先后次序,所以我们要记录好每一个获得科技创新奖的人的编号的位置,并记录好原科技创新奖获奖名单中的先后次序.

直接输出排序后的编号只有20分
我的惨痛经历,调了30分钟

代码如下:

#include<algorithm>
#include<stdio.h>
#define MAXN 100005
using namespace std;
class node{
	public:
		int w,
			x;
}a[MAXN];//科技创新奖的人的编号,其中w是编号,x是位置
int n,m,b[MAXN],ai=1,bi=1,aa[MAXN],c[MAXN],k;
//b数组w为特殊贡献奖的人的位置,由于不需要先后顺序,直接用int型数组
//c数组存储了两个奖项都获得了的人的科技创新奖的位置,用于输出
//aa是原先科技创新奖获奖名单,用于输出
//ai,bi为a数组和b数组指针,k是用于记录c数组的指针
inline static bool cmp1(int x,int y){
	return x<y;
}
inline static bool cmp2(node x,node y){
	return x.w<y.w;
}
//都按升序排列
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i].w);
		aa[i]=a[i].w,a[i].x=i;
	}
	for(int i=1;i<=m;i++)scanf("%d",&b[i]);
//输入部分
	sort(a+1,a+n+1,cmp2);
	sort(b+1,b+m+1,cmp1);
//排序
	while(ai<=n and bi<=m){
		if(a[ai].w<b[bi])ai++;//当前ai所指的值比bi所指小,说明相等的编号在ai右侧,向右移
		if(a[ai].w>b[bi])bi++;//同理
		if(a[ai].w==b[bi]){//相等则记录
			c[++k]=a[ai].x;
			ai++,bi++;//跳过相等的值
		}
	}
	sort(c+1,c+k+1,cmp1);//对相等编号的位置排序,这样就是按照先后顺序的啦
	for(int i=1;i<=k;i++){
		printf("%d ",aa[c[i]]);//按原先后顺序输出编号
	}
	return (0^0);//结束撒花
}