hdu 5821 Ball 2016 Multi-University 8

Problemacm.hdu.edu.cn/showproblem.php?pid=5821

题意:给两个长度为 n 的数的序列 a 和 b,问 a 能不能在 m 次操作后变成 b

每次操作都是给个区间 [ l,r ],把此区间的所有数拿出来然后任意重排后放回去

分析:如果 a 和 b 中相同的数有相等多个的话,可以对每一个 ai 都指定一个目标下标 j,使得 bj 是 b 中第1个与 ai 相等的数,然后每次重排操作都按照目标下标的大小升序排

操作完后,判断每一个 ai 是否都去到了应去的位置

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 1000
typedef struct
{
	int v;
	int to; // 目标下标
}node;

node a[N];
int b[N];
// a[]、b[]的副本,用来判断a[]和b[]同一个数的数量是否相等
int tmpa[N],tmpb[N];
// 标记当前bj是否已被某ai标为目标
char un[N];

int cmpint(const void *aa, const void *bb)
{
	return *(int*)aa - *(int*)bb;
}

int cmpnode(const void *aa, const void *bb)
{
	const node *cc = aa, *dd = bb;
	return cc->to - dd->to;
}

int main()
{
	int iTom;
	scanf("%d", &iTom);
	while( iTom-- )
	{
		int n,m,i,j,no;
		scanf("%d%d", &n, &m);
		for(i=0; i<n; i++)
		{
			scanf("%d", tmpa+i);
			a[i].v = tmpa[i];
		}
		for(j=0; j<n; j++)
		{
			scanf("%d", b+j);
			tmpb[j] = b[j];
		}
		// 判断a[]和b[]同一个数的数量是否相等
		qsort(tmpa, n, sizeof(int), cmpint);
		qsort(tmpb, n, sizeof(int), cmpint);
		for(i=0; i<n; i++)
		  if( tmpa[i] - tmpb[i] ) // a[]与b[]不全相同
			break;
		no = i<n;
		// 每个ai配目标下标
		memset(un, 't', sizeof(un));
		for(i=0; i<n; i++)
		  for(j=0; j<n; j++)
			if( a[i].v == b[j] && un[j] )
			{
				un[j] = '\0';
				a[i].to = j;
				break;
			}
		while( m-- )
		{
			int l,r;
			scanf("%d%d", &l, &r);
			qsort(a+l-1, r-l+1, sizeof(node), cmpnode);
		}
		if( !no )
		{
			for(i=0; i<n; i++)
			  if( a[i].to - i ) // 某ai未到目标位置
				break;
			no = i<n;
		}
		puts( no? "No": "Yes" );
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值