UVa140 Bandwidth (枚举排列)

链接:http://acm.hust.edu.cn/vjudge/problem/19399分析:将结点字母用数字0~n-1表示,id[ch]将字符映射到对应的数字编号,letter将数字编号映射到对应的字符,用两个vector将每个结点的相邻结点编号存下来,然后枚举0~n-1位置上的结点编号,用pos记录每个结点编号所在的位置方便以后查找,然后就是遍历vector,第一个vector代表结点编号i,第二个vector代表结点i的相邻结点编号,找出最远距离,如果当前找到的最远距离已经大于或等于ans,则不能更优应剪枝,然后就是更新ans和bestP,直至枚举完0~n-1的所有排列。
 1 #include <cstring>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7
 8 const int maxn = 10;
 9 int id[256], letter[maxn];
10
11 int main() {
12     char input[1000];
13     while (scanf("%s", input) == 1 && input[0] != ‘#‘) {
14         int n = 0;
15         for (char ch = ‘A‘; ch <= ‘Z‘; ch++)
16             if (strchr(input, ch) != NULL) {
17                 id[ch] = n++;
18                 letter[id[ch]] = ch;
19             }
20         vector<int> u, v;
21         int len = strlen(input);
22         for (int p = 0, q = 0; q < len; p++, q++) {
23             while (input[p] != ‘:‘) p++;
24             while (q < len && input[q] != ‘;‘) q++;
25             for (int i = p + 1; i < q; i++) {
26                 u.push_back(id[input[p - 1]]);
27                 v.push_back(id[input[i]]);
28             }
29         }
30         int pos[maxn], P[maxn], bestP[maxn], ans = n;
31         for (int i = 0; i < n; i++) P[i] = i;
32         do {
33             for (int i = 0; i < n; i++) pos[P[i]] = i;
34             int bandwidth = 0;
35             for (int i = 0; i < u.size(); i++) {
36                 bandwidth = max(bandwidth, abs(pos[u[i]] - pos[v[i]]));
37                 if (bandwidth >= ans) break;
38             }
39             if (bandwidth < ans) {
40                 ans = bandwidth;
41                 memcpy(bestP, P, sizeof(P));
42             }
43         } while (next_permutation(P, P + n));
44         for (int i = 0; i < n; i++) printf("%c ", letter[bestP[i]]);
45         printf("-> %d\n", ans);
46     }
47     return 0;
48 }
时间: 2024-12-14 02:19:47

UVa140 Bandwidth (枚举排列)的相关文章

蓝桥杯 2014本科C++ B组 六角填数 枚举排列

标题:六角填数 如图[1.png]所示六角形中,填入1~12的数字. 使得每条直线上的数字之和都相同. 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少? 请通过浏览器提交答案,不要填写多余的内容. 简单的枚举排列,只要提前将12个结点标号,来判断六个线段总和是否相等. 代码如下: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define MAXN 13 5 int num

poj 1270 Following Orders 枚举排列

题意: 给一个字符集和一些字符之间的小于关系,求字符集上的所有可能排列. 分析: 暴力枚举可以分为枚举子集,枚举排列,枚举组合,这题是个简单的枚举排列,枚举过程中用小于关系剪枝即可. 代码: //poj 1270 //sep9 #include <iostream> #include <algorithm> using namespace std; char vars[64],constraint[256],ans[64]; int g[128][128],vis[256]; in

ACM:回溯法,枚举排列

(一)生成1~n的排列 分析:用递归的思想解决:先输出所有以1开头的排列(这一步是递归调用),然后输出以2开头的排列(又是递归调用),接着是以3开头的排列......最后才是以n开头的排列. 伪代码: void print_permutation(序列A, 集合S) { if(S为空) 输出序列A: else 按照从小到大的顺序依次考虑S的每个元素v { print_permutation(在A的末尾填加v后得到的新序列,S-{v}): } } 下面是实现代码: #include <iostre

poj 2585 Window Pains 暴力枚举排列

题意: 在4*4的格子中有9个窗体,窗体会覆盖它之下的窗体,问是否存在一个窗体放置的顺序使得最后的结果与输入同样. 分析: 在数据规模较小且不须要剪枝的情况下能够暴力(思路清晰代码简单),暴力一般分为枚举子集(for(s=0;s<1<<n;++s))和枚举排列(next_permutation). 代码: //poj 2585 //sep9 #include <iostream> #include <algorithm> using namespace std;

枚举排列 之 “生成1~n的排列”

一.原题 输入n之后,生成1~n的排列. (题目来源:<算法竞赛入门经典>[刘汝佳]) 二.题目源代码 #include <stdio.h> #define MAXN 1000 int a[MAXN][MAXN]; void print_permutation(int n,int*a,int cur) { int i,j; if(cur==n) //递归边界 { for(i=0;i<n;i++) printf("%d",a[i]); printf(&quo

UVa 140 (枚举排列) Bandwidth

题意较复杂,请参见原题=_=|| 没什么好说的,直接枚举每个排列就好了,然后记录最小带宽,以及对应的最佳排列. STL里的next_permutation函数真是好用. 比较蛋疼的就是题目的输入了.. 还有就是不明白,为什么19.20行注释哪错了?? 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 10; 5 6 int id[256], letter[maxn]; 7 char in[1000];

UVa140 Bandwidth 小剪枝+双射小技巧+枚举全排列+字符串的小处理

给出一个图,找出其中的最小带宽的排列.具体要求见传送门:UVa140 这题有些小技巧可以简化代码的编写. 本题的实现参考了刘汝佳老师的源码,的确给了我许多启发,感谢刘老师. 思路: 建立双射关系:从字符A到字符Z遍历输入的字符串,用strchr函数将输入中出现的字符找出,并将找出的字符进行编号,用letter和id分别存储字符和对应的编号 降维:输入中给出的,是类似于邻接表形式的二维形式,如果我们用二维数据结构,将增加处理时对于输出细节的处理难度,用 2个 vector将输出降低到1维,简化了计

Uva140 Bandwidth 全排列+生成测试法+剪枝

参考过仰望高端玩家的小清新的代码... 思路:1.按字典序对输入的字符串抽取字符,id[字母]=编号,id[编号]=字母,形成双射       2.邻接表用两个vector存储,存储相邻关系       3.先尝试字母编号字典序最小的排列,此为next_permutation的最上排列       4.在最理想的情况下都不能得到比当前最优解更好的方案,则应当剪枝(prune)       5.memcpy(),strchr()方法来自于库函数 测试集: Input:      A:FB;B:GC

uva140 Bandwidth

https://vjudge.net/problem/UVA-140 给出一个图,构造一个排列,使图上相邻节点在排列中的距离最大值最小 没有剪枝,竟然10ms过了,~~~ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; bool b[26][26],use[10]; char s[100],ans[10],tmp[26]; int len,v[26],num,minn