【uva 1610】Party Games(算法效率--构造 dfs)

题意:有一个N个字符串(N≤1000,N为偶数)的集合,要求找一个长度最短的字符串(可不在集合内)S,使得集合中恰好一半的串小于等于S,另一半大于S。如果有多解,要求输出字典序最小的解。

解法:本来我是想分析情况用if else实现的,但是细节很多,特别容易错。结果果然如此。╮(╯_╰)╭ 那么便看看搜索行不行,由于要求字典序最小,也就是长度尽量小的情况下字符尽量小。而且要集合中恰好一半的串小于等于S,另一半大于S,也就是排序后>=中间靠左边的串且<中间靠右边的串。那么我们可以对排序后的中间的2个串从前面开始扫,出现不一样的字符时,就枚举‘A‘~‘Z‘,看看是否符合题目条件。如果这个长度的串都不满足,那么就这个位填当前符合条件的最小的字符,再对下一位搜索,也就是像bfs一样每位全部搜索完才到下一位。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7
 8 const int N=1010,L=510;
 9 int n;
10 char s[L];
11 struct node{char s[L];int l;}a[N];
12
13 bool cmp(node x,node y) {return strcmp(x.s,y.s)<0;}
14 void bfs(int x,int y,int i)
15 {
16     if (i>a[y].l&&i>a[x].l) return;//&&
17     int t;
18     if (i<a[x].l) t=a[x].s[i]-‘A‘;
19     else t=0;
20     for (int j=t;j<26;j++)
21     {
22       s[i]=‘A‘+j;
23       if (strcmp(a[x].s,s)<=0 && strcmp(a[y].s,s)>0) return;
24     }
25     s[i]=‘A‘+t;//
26     bfs(x,y,i+1);
27 }
28 int main()
29 {
30     while (1)
31     {
32       scanf("%d",&n);
33       if (!n) break;
34       for (int i=1;i<=n;i++)
35       {
36         scanf("%s",a[i].s);
37         a[i].l=strlen(a[i].s);
38       }
39       sort(a+1,a+1+n,cmp);
40       memset(s,‘\0‘,sizeof(s));
41       int x=(1+n)/2,y=x+1;
42       bool ok=false;
43       int t=0;
44       for (int i=0;i<a[x].l;i++)
45       {
46         int u=a[x].s[i]-‘A‘,v=a[y].s[i]-‘A‘;
47         if (u!=v) {bfs(x,y,i); break;}
48         s[i]=a[x].s[i];
49       }
50       printf("%s\n",s);
51     }
52     return 0;
53 }
时间: 2024-11-03 22:35:19

【uva 1610】Party Games(算法效率--构造 dfs)的相关文章

UVa 12118 nspector&#39;s Dilemma (构造+DFS+欧拉回路)

题意:给定n个点,e条边和每条边的长度t,每两个点之间都有路相连,让你求一条最短的路经过这e条边. 析:刚开始想到要判连通,然后把相应的几块加起来,但是,第二个样例就不过,后来一想,那么有欧拉回路的还得加1啊. 又想每次再判一次是不是欧拉回路,怎么判又是问题,因为并不知道哪些是连在一块的,还得再查找,麻烦啊.... 后来上网看了一下题解,原来是要构造啊,也就是说把每个连通块都构造成一个欧拉回路,那么再减去端点的,就能完全连通了. 真是好方法,欧拉回路满足每个点的度都是偶数,也就是说如果不是偶数那

Uva 1610 Party Games

Thinking about it: 刚开始思考的时候,脑子里就觉得这道题可能有很多情况,刚开始就因为考虑不周全wa了. 后来换了一种思路,如果不能马上就直接得到答案,就一个一个字母去尝试.这样子就有点类似dfs了,比如 名字排序后排在中间的z字符串是 s1,,s2,那么第i位的字母肯定介于 s1[i] 和 s2[i] 之间,然后先判断在这里填一个字母能否得出答案.这里需注意:不能填了一个字母后就立马搜索下一个情况,因为题目首先要求是最短,所以要在不填下一个字母的情况下,把这个位置可能的字母都填

UVA - 1610 Party Games (字符串比较)

给你n(n为偶数)个字符串,让你找出一个长度最短且字典序尽量小的字符串,使得一半的字符串小于等于该串,一半的字符串大于该串. 紫薯上说这道题有坑,但其实思路对了就没什么坑. 很明显,只要取夹在中间两个字符串间的最小字符串就行了.可以从小到大枚举字符串的长度,如果该长度下存在满足条件的字符串则返回结果,否则把较小的字符串上对应位的字符加到末尾就行了. 因为想错思路WA了好几次,最后一次WA居然是忘了判断n=0的情况...(为什么我总是完美避开正确答案,QAQ) 1 #include<bits/st

【uva 1615】Highway(算法效率--贪心 区间选点问题)

题意:给定平面上N个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个店,都有一个选出的点离它的欧几里德距离不超过D. 解法:先把问题转换成模型,把对平面的点满足条件的点在x轴的直线上可得到一个个区间,这样就是选最小的点覆盖所有的区间的问题了.我之前的一篇博文有较详细的解释:关于贪心算法的经典问题(算法效率 or 动态规划).代码实现我先空着.挖坑~

训练指南 UVA - 11383(KM算法的应用 lx+ly &gt;=w(x,y))

layout: post title: 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y)) author: "luowentaoaa" catalog: true mathjax: true tags: - KM算法 - 训练指南 Golden Tiger Claw UVA - 11383 题意 给一个n*n的矩阵,每个格子中有正整数w[i[j],试为每行和每列分别确定一个数字row[i]和col[i],使得任意格子w[i][j]<=row[i

快速排序里的学问:枢纽元选择与算法效率

选择首尾元素做枢纽元 通常的.没有经过充分考虑的选择是将第一个或最后一个元素用作枢纽元.选择第一个元素作为枢纽元的程序例子可以参考专题的前一篇<快速排序里的学问:霍尔快排的实现>,而选择最后一个元素用作枢纽元的程序例子则可以参考<快速排序里的学问:快速排序的过程>这个算法导论里的例子. 选择最后一个元素作为枢纽元的排序过程是这样的: 如果输入是随机的,那么这是可以接受的,但是如果输入是预排序的或者是反序的,那么这样的枢纽元就产生一个劣质的分割,因为所有的元素不是被划入S1就是被划入

枢纽元选择与算法效率

选择首尾元素做枢纽元 通常的.没有经过充分考虑的选择是将第一个或最后一个元素用作枢纽元.选择第一个元素作为枢纽元的程序例子可以参考专题的前一篇<快速排序里的学问:霍尔快排的实现>,而选择最后一个元素用作枢纽元的程序例子则可以参考<快速排序里的学问:快速排序的过程>这个算法导论里的例子. 选择最后一个元素作为枢纽元的排序过程是这样的:威尼斯人赌场 如果输入是随机的,那么这是可以接受的,但是如果输入是预排序的或者是反序的,那么这样的枢纽元就产生一个劣质的分割,因为所有的元素不是被划入S

数据结构和算法学习总结02 算法效率的度量

算法的效率 我们度量算法效率方式:事前分析估算方法       在计算机程序编写前,依据统计方法对算法进行估算 算法的效率的度量是抽象的,而不是进行精确的测量,忽略硬件方面.程序编译优化,代码循环终止条件和变量声明等因素 下面把函数当成一般的算法进行效率的判断 例子: 函数 n=1 2 3 100 省略后 n+2 3 4 5 102 100 2n+1 3 5 7 201 200 2n+2 4 6 8 202 100 2n^2+2 4 10 20 20002 10000 2n^2+n+2 5 12

编程算法 - 数组构造二叉树并打印

数组构造二叉树并打印 本文地址: http://blog.csdn.net/caroline_wendy 数组: 构造二叉树, 需要使用两个队列(queue), 保存子节点和父节点, 并进行交换; 打印二叉树, 需要使用两个队列(queue), 依次打印父节点和子节点, 并进行交换; 二叉树的数据结构: struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pParent; BinaryTreeNode* m_pLeft; BinaryT