枚举特训:带宽(UVA140)双映射,全排列枚举

该博客介绍了如何使用枚举算法解决UVA140问题,通过建立字母与整数的双映射关系,实现全排列并计算带宽。博主分享了三种解题技巧,包括双映射应用、无需存储连接状态的双数组方法和记录数字位置的pos数组。题目要求连接给定点,找出所有排列中最短的连接距离(最大位置差)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解题思路:针对每一个字母,可以定义两个数组使其与连续的整数形成相互映射。接着定义两个vector,根据输入的连接形成一一对应关系,即同一个下标i,vector a[i]与b[i]相连。接着枚举排列,遍历vector得到每一个排列的带宽,并更新最小总带宽。

技巧学习:

1.双映射的巧妙应用,每一个字母用整数与之对应(我们并不需要直到每个字母具体对应哪一个整数)

2.使用双数组形成一一对应关系,无需特别存储某个字母与其他多个字母相连的状态。

3.添加pos数组记录数字对应的位置。

具体查看下面的代码。

题目大意:给出一些点(A,B,C,D...),以及所有必须相连的两点,代表这些点的字母可以组成不同的排列。然后每个排序中,遍历每个点及其相连关系,找出连接距离(即在排列中的位置差)的最大值,然后在所有排列中找出连接所需最短的。

Sample input

A:FB;B:GC;D:GC;F:AGH;E:HD
#

Sample output

A B C F G D H E -> 3

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
	char a[300],letter[300];
	int id[300];
	while(scanf("%s",a)!=EOF)
	{
		int len=strlen(a),p=0,q=0,n=0;
		for(char ch='A';ch<='Z';ch++)
		{
			if(strchr(a,ch)!=NULL)     //使字符与数字形成双映射 
			{
				id[ch]=n++;
				letter[id[ch]]=ch;
			}
		}
		vector<int> u,v;
		while(1)
		{
			if(q>=len) break;           //不能直接写q==len,可能存在q直接跳过len的情况 
			while(p<len&&a[p]!=':') p++;   //找到:位置 
			//if(p==len) break;
			while(q<len&&a[q]!=';') q++;   //找到;位置 
			for(int i=p+1;i<q;i++)         //遍历中间元素,使得一一对应 
			{
				u.push_back(id[a[p-1]]);
				v.push_back(id[a[i]]);
			}
			p++;q++;
		}
		
		int P[300],POS[300],best[300];
		for(int i=0;i<n;i++) P[i]=i;
		int ans=n;
		do{                       //找出每一种排列的带宽 
			for(int i=0;i<n;i++) POS[P[i]]=i;    //巧妙地记录字母位置 
			int bandwidth=0;
			for(int i=0;i<u.size();i++)
			{
				bandwidth=max(bandwidth,abs(POS[u[i]]-POS[v[i]]));
			}
			if(bandwidth<ans)   //更新最小总带宽 
			{
				ans=bandwidth;
				memcpy(best,P,sizeof(int)*n);
			}
		}while(next_permutation(P,P+n));
		for(int i=0;i<n;i++)
		printf("%c ",letter[best[i]]);
		printf("-> %d\n",ans);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值