题目概述:Anagrams by Stack

  How can anagrams result from sequences of stack operations? There are two sequences of stack operators which can convert TROT to TORT:

[

i i i i o o o o

i o i i o o i o

]

  where i stands for Push and o stands for Pop. Your program should, given pairs of words produce sequences of stack operations which convert the first word to the second.

Input

  The input will consist of several lines of input. The first line of each pair of input lines is to be considered as a source word (which does not include the end-of-line character). The second line (again, not including the end-of-line character) of each pair is a target word. The end of input is marked by end of file.

Output

  For each input pair, your program should produce a sorted list of valid sequences of i and o which produce the target word from the source word. Each list should be delimited by

[

]

  and the sequences should be printed in "dictionary order". Within each sequence, each i and o is followed by a single space and each sequence is terminated by a new line.

Process

  A stack is a data storage and retrieval structure permitting two operations:

Push - to insert an item and

Pop - to retrieve the most recently pushed item

  We will use the symbol i (in) for push and o (out) for pop operations for an initially empty stack of characters. Given an input word, some sequences of push and pop operations are valid in that every character of the word is both pushed and popped, and furthermore, no attempt is ever made to pop the empty stack. For example, if the word FOO is input, then the sequence:

i i o i o o

is valid, but

i i o

is not (it's too short), neither is

i i o o o i

(there's an illegal pop of an empty stack)

  Valid sequences yield rearrangements of the letters in an input word. For example, the input word FOO and the sequence i i o i o o produce the anagram OOF. So also would the sequence i i i o o o. You are to write a program to input pairs of words and output all the valid sequences of i and o which will produce the second member of each pair from the first.

Sample Input

madam

adamm

bahama

bahama

long

short

eric

rice

Sample Output

[

i i i i o o o i o o

i i i i o o o o i o

i i o i o i o i o o

i i o i o i o o i o

]

[

i o i i i o o i i o o o

i o i i i o o o i o i o

i o i o i o i i i o o o

i o i o i o i o i o i o

]

[

]

[

i i o i o i o o

]


简单描述

 

输入要求

  输入由多行组成,每对单词占2行。第1行为原始单词(不包括行尾的换行符),第2行为目标单词(同样不包括行尾的换行符)。

输出要求

  对于输入的每一对字符串,你的程序应该按顺序生成所有的有效的进出栈操作列表,其中的每组操作都能使原字符串转变为目标字符串。每一组操作要由方括号括起来,其中i表示压入,o表示弹出。

程序要求

  可能有多组有效操作都能够为输入的单词生成指定的字母排列。比如对于输入的单词“FOO”,操作i i o i o o就可以生成重排的单词“OOF”。操作i i i o o o也可以生成同样的重排。你要写一个程序,找出所有有效的操作序列,以使输入的一对单词的前者重排为后者。


题目分析

  这道题必须遍历所有可能的进出栈序列才能求得全部解。因此同Crashing Balloon解法一样,属于DFS(深度优先搜索)加回溯。


解题算法

  注释相当完整,如题

#include<stdio.h>
#include<string.h>
#define MAX_LEN 100
#define STACK_SIZE 200 char source[MAX_LEN], /* 源字符串 */
target[MAX_LEN], /* 目标字符串 */
stack[STACK_SIZE]; /* 栈*/
int state[2*MAX_LEN]; /* 每一阶段的状态,也就是路径OR解,状态1表示压栈;-1表示弹栈 */
int len; /* 字符串长度 */
int flag=0; /* 标记是否有解 */ int print(int depth) /* 输出结果 */
{
int i=0;
while(i<depth-1) /* 这里是i<depth-1不是i<depth否则会多出空格 */
{
if(state[i]==1) /* 用1表示压栈;-1表示弹栈 */
putchar('i');
if(state[i]==-1)
putchar('o');
if(i<depth-1) /* ATTENTION!不是每一个后面都有空格,最后一个字符后没有! */
putchar(' ');
i++;
}
putchar('\n');
return 0;
} int dfs(int depth,int npush,int npop) /* depth:深搜的深度;npush:压栈数;npop:弹栈数 */
{
if(npush==len&&npop==len) /* 求解完成 */
{
flag=1; /* 修改标志:有解 */
print(depth); /* 输出解 */
return 0;
}
if(npush<len) /* 可以压栈 */
{
state[depth-1]=1; /* 记录状态,1表示入栈 */
stack[stack[0]]=source[npush]; /* 入栈,将源npush位置的字符压入栈顶 */
stack[0]++; /* 改变栈顶指针,栈后移 */
dfs(depth+1,npush+1,npop); /* GO ON,进行压栈判断 */
stack[0]--; /* 回溯要恢复栈的状态,因为不是每一次调用都复制一次栈。那样开销大 */
}
if(stack[0]>0&&target[npop]==stack[stack[0]-1]) /* 判断是否可以弹栈,不能弹栈就回溯 */
{
state[depth-1]=-1; /* 记录状态, -1表示弹栈 */
int tmp=stack[stack[0]-1]; /* 因为要弹栈,所以要保存栈原来的状态,tmp记录的是栈顶的位置 */
stack[0]--; /* 改变栈顶指针 */ dfs(depth+1,npush,npop+1); /* 继续DFS,进行弹栈判断 */
stack[stack[0]]=tmp; /* 不能弹栈就回溯,恢复栈的状态 */
stack[0]++; /* 恢复栈顶指针 */
}
return 0;
} int main(void)
{
stack[0]=1; /* stack[0]指向栈顶的上一位;初始化*/
while(scanf("%s%s",source,target)!=EOF)
{
puts("[");
flag=0; /* 初始化标志 */
len=strlen(source);
if(len==strlen(target)) /* 长度不同=》跳过 */
dfs(1,0,0);
puts("]");
}
return 0;
}

【Acm】算法之美—Anagrams by Stack的更多相关文章

  1. HDU ACM 1515 Anagrams by Stack

    Anagrams by Stack Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  2. ZOJ 1004 Anagrams by Stack(DFS+数据结构)

    Anagrams by Stack 题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4 题目大意:输入两个字符串序列,判 ...

  3. JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)

    前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...

  4. ZOJ 1004 Anagrams by Stack

    Anagrams by Stack 题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1004 题意:通过堆栈实现将一 ...

  5. stack+DFS ZOJ 1004 Anagrams by Stack

    题目传送门 /* stack 容器的应用: 要求字典序升序输出,所以先搜索入栈的 然后逐个判断是否满足答案,若不满足,回溯继续搜索,输出所有符合的结果 */ #include <cstdio&g ...

  6. 【EatBook】-NO.2.EatBook.2.JavaArchitecture.1.001-《修炼Java开发技术在架构中体验设计模式和算法之美》-

    1.0.0 Summary Tittle:[EatBook]-NO.2.EatBook.2.JavaArchitecture.1.001-<修炼Java开发技术在架构中体验设计模式和算法之美&g ...

  7. ACM,算法

    ACM,算法 描述 最近Topcoder的XD遇到了一个难题,倘若一个数的三次方的后三位是111,他把这样的数称为小光棍数.他已经知道了第一个小光棍数是471,471的三次方是104487111,现在 ...

  8. Anagrams by Stack(深度优先搜索)

    ZOJ Problem Set - 1004 Anagrams by Stack Time Limit: 2 Seconds      Memory Limit: 65536 KB How can a ...

  9. 推荐学习《算法之美:指导工作与生活的算法》中文PDF+英文PDF

    我们所有人的生活都受到有限空间和有限时间的限制,因此常常面临一系列难以抉择的问题.在一天或者一生的时光里,哪些事是我们应该做的,哪些是应该放弃的?我们对杂乱无序的容忍底线是什么?新的活动与熟悉并喜爱的 ...

随机推荐

  1. ubuntu 安装 oracle-xe-universal

    安装oracle-xe-universal第一个我们要考虑的就是交换分区是否足够大, 如果你直接安装,可能会出现下面的英文提示: This system does not meet the minim ...

  2. 内存问题排查工具 --- valgrind

    1. 概述 2. Valgrind 3. 内存泄漏监测 3.1. 示例代码 3.2. 编译它 3.3. 用Valgrind监测进程的内存泄漏 4. 悬挂指针 4.1. 示例代码 4.2. Valgri ...

  3. 使用Java调用JS

    import junit.framework.TestCase; import javax.script.ScriptEngine; import javax.script.ScriptEngineM ...

  4. HTML 5 应用程序缓存(Application Cache)cache manifest 文件使用 html5 中创建manifest缓存以及更新方法 一个manifest文件会创建一份缓存,不同的manifest文件其缓存的内容是互不干扰的

    HTML5 离线缓存-manifest简介 HTML 5 应用程序缓存 使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本. 什么是应用程序缓存(A ...

  5. Android之Activity系列总结(三)--Activity的四种启动模式

    一.返回栈简介 任务是指在执行特定作业时与用户交互的一系列 Activity. 这些 Activity 按照各自的打开顺序排列在堆栈(即返回栈,也叫任务栈)中. 首先介绍一下任务栈: (1)程序打开时 ...

  6. 进阶之路(中级篇) - 016 温湿度传感器DHT11

    如果想使用 Arduino 开发板驱动 DHT11 来获取温湿度的时候建议使用第三方的库,这样可以加快程序的开发速度,而且不容易出错,下面的代码我已经安转了第三方的库了.详细的安装方法请参考极客先锋的 ...

  7. HDU 1907 John (Nim博弈)

    John Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submis ...

  8. 【Oracle】详解ORACLE中的trigger(触发器)

    本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 触发器触发次序 8.2.2 创建DML触发器 8.2. ...

  9. js事件之event.preventDefault()与(www.111cn.net)event.stopPropagation()用法区别

    event.preventDefault()用法介绍 该方法将通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作).例如,如果 type 属性是 "submit" ...

  10. CentOS7安装Tomcat

    一.二进制包安装Tomcat 1.下载解压二进制包 wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.32/bi ...