C++ HOJ 火车进站
【问题描写叙述】
给定一个正整数N代表火车数量。0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号。
要求以字典序排序输出火车出站的序列号。
输入:
有多组測试用例,每一组第一行输入一个正整数N(0<N<10),第二行包含N个正整数,范围为1到9。
输出:
输出以字典序排序的火车出站序列号,每一个编号以空格隔开,每一个输出序列换行。详细见sample。
例子输入:
3
1 2 3
例子输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
【解题思路一】
栈具有先进后出、后进先出的特点,因此,不论什么一个调度结果应该是1 ,2 ,3 ,4全排列中的一个元素。因为进栈的顺序是由小到大的,所以出栈序列应该满足下面条件:对于序列中的不论什么一个数其后面全部比它小的数应该是倒序的,比如4321 是一个有效的出栈序列,1423不是一个有效的出栈结果(4 后面比它小的两个数 2 ,3 不是倒序)。
据此。本题能够通过算法产生n 个数的全排列,然后将满足出栈规则的序列输出。
依此递归定义。递归算法例如以下:
#include<stdio.h>
int cont=1;
void print(int str[],int n);
void perm(int str[],int k,int n)
{
int i,temp;
if(k==n-1)print(str,n);//k和n-1相等。即一趟递归走完
else{
for(i=k;i<n;i++){//把当前节点元素与兴许节点元素交换
temp=str[k]; str[k]=str[i]; str[i]=temp;//交换
perm(str,k+1,n);//把下一个节点元素与兴许节点元素交换
temp=str[i]; str[i]=str[k]; str[k]=temp;//恢复原状
}
}
}
/* 本函数推断整数序列 str[] 是否满足进出栈规则, 若满足则输出*/
void print(int str[],int n)
{
int i,j,k,l,m,flag=1,b[2];
for(i=0;i<n;i++) /* 对每一个str[i] 推断其后比它小的数是否为降序序列*/
{
m=0;
for(j=i+1;j<n&&flag;j++){
if (str[i]>str[j])
{
if (m==0) b[m++]=str[j];//记录str[i]后比它小的数
else
{
//假设之后出现的数比记录的数还大,改变标记变量
if (str[j]>b[0]) flag=0;
//否则记录这个更小的数
else b[0]=str[j];
}
}
}
}
if(flag) /* 满足出栈规则则输出 str[] 中的序列*/
{
printf(" %2d:",cont++); //输出序号
for(i=0;i<n;i++)
printf("%d",str[i]);//输出序列
printf("\n");
}
}
int main()
{
int str[100],n,i;
printf("input a int:"); /* 输出排列的元素个数*/
scanf("%d",&n);
for(i=0;i<n;i++) /* 初始化排列集合*/
str[i]=i+1; //第i个节点赋值为i+1
printf("input the result:\n");
perm(str,0,n); //调用递归
printf("\n");
return 0;
}
【解题思路二】
此处所谓字典序排序的意思是这n辆火车有多少种出站的可能顺序(也就是数据结构中的栈有多少种出栈顺序)。思路为用三个变量分别存储待进站火车,站中火车和已出站火车,当中待进站火车用Queue(队列)存储和站中火车採用stack(栈)存储,已出站火车採用StringBuilder来存储,详细实现是採用递归的方法,递归函数的參数为当前待进站火车、站中火车、已出站火车的值所组成的三元组,递归结束条件是。未进站火车和站中火车均为空。此时输出已出站火车即为全部出站的一种可能,递推关系为对于当前情况有让下一辆火车进站或让站中的一辆火车出站两种可能,对于两种可能分别调用递归函数。就可以得出问题的解。
【Java 实现】
【解题思路三】
该问题能够提炼成为给出进栈序列。求出全部的出栈顺序。该题是一道模拟题,模拟进栈出栈的顺序。对于每个元素进栈后 都能够有2种行为:出栈或者驻留在栈中。整个过程能够用一个树的形式来表达。因此採用回朔法(回溯法的过程就是一课树的形式)
//回溯法。其核心就是循环+递归。为了表示正确性,当中每一步操作(如改动数据,进栈等)
//都应该有对应的对称操作还原(如将改动数据还原,出栈等)
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
int num;
int input[10];
int output[10];
int output_index;
int heap[10];
int heap_index;
vector<int* >vec;
void DF(int n);
void df(int n)
{
if(heap_index==0)
return ;
//退出栈 放入输入队列中
output[output_index++]=heap[--heap_index]; //对称1
heap[heap_index]=0;
for(int i=0;i<2;i++)
{
if(i==0)
df(n);
else
DF(n+1);
}
heap[heap_index++]=output[--output_index]; //对称1
output[output_index]=0; } void DF(int n)
{
heap[heap_index++]=input[n]; //放入 。对称2
if(n==num-1) //该函数退出时(一般在回溯法中,在函数出口内部是不存在对称结构,可是该题中存在其它函数df调用该回溯函数,故返回到)
{
int temp=heap_index;
output[output_index++]=heap[--heap_index]; //对称3
heap[heap_index]=0; while(heap_index)
output[output_index++]=heap[--heap_index];
int *p=(int *)malloc(sizeof(int)*num);
for(int i=0;i<output_index;i++)
p[i]=output[i];
vec.push_back(p);
while(temp) //对称3
{
heap[heap_index++]=output[--output_index];
output[output_index]=0;
temp--;
}
heap[--heap_index]=0; //对称2
return ; }
for(int i=0;i<2;i++)
{
if(i==0)
df(n);
else
DF(n+1); //i==1的时候就是不将数据退出栈
}
heap[--heap_index]=0; //对称2 } bool cmp(int* t1,int* t2)
{
for(int i=0;i<num;i++)
{
if(t1[i]==t2[i])
continue;
return t1[i]<t2[i];
}
return true;
}
int main()
{
freopen("a.txt","r",stdin);
while(scanf("%d",&num)!=EOF)
{
memset(input,0,sizeof(input));
memset(output,0,sizeof(input));
memset(heap,0,sizeof(input));
output_index=0;
heap_index=0;
vec.clear();
for(int i=0;i<num;i++)
scanf("%d",input+i);
DF(0);
sort(vec.begin(),vec.end(),cmp);
for(unsigned int i=0;i<vec.size();i++)
{
for(int j=0;j<num-1;j++)
printf("%d ",vec[i][j]);
printf("%d\n",vec[i][num-1]);
}
}
return 0;
}
【解题思路四】
STL方法:1、若n=1那么就一种排列方式。2、n>1时先求出n-1的出栈顺序。再分开将n插入n-1之前。n-1之后和每个n-1之后的每个数!
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std; void helper(string &inTrain,vector<string> &outTrain,int index){
if(index == inTrain.size()){
return;
}//if
if(index == 0){
string outNum("");
outNum += inTrain[index];
outTrain.push_back(outNum);
}//if
else{
vector<string> newOutTrain;
// 出栈序列
int size = outTrain.size();
// 第index辆火车进栈
for(int i = 0;i < size;++i){
// 第i个出栈序列
int count = outTrain[i].size();
// 寻找前一个进栈的火车下标
int targetIndex;
for(int j = 0;j < count;++j){
if(inTrain[index-1] == outTrain[i][j]){
targetIndex = j;
break;
}//if
}//for
string tmp(outTrain[i]);
for(int j = targetIndex;j <= count;++j){
tmp.insert(tmp.begin()+j,inTrain[index]);
newOutTrain.push_back(tmp);
tmp.erase(tmp.begin()+j);
}//for
}//for
swap(outTrain,newOutTrain);
}//else
helper(inTrain,outTrain,index+1);
} vector<string> TrainLeft(string inTrain){
vector<string> result;
int size = inTrain.size();
if(size <= 0){
result;
}//if
helper(inTrain,result,0);
sort(result.begin(),result.end());
return result;
} int main(){
int n;
//freopen("C:\\Users\\Administrator\\Desktop\\c++.txt","r",stdin);
while(cin>>n){
string train("");
int num;
for(int i = 1;i <= n;++i){
cin>>num;
train += num + '0';
}//for
vector<string> trainNum = TrainLeft(train);
// 输出
int size = trainNum.size();
for(int i = 0;i < size;++i){
int count = trainNum[i].size();
for(int j = 0;j < count;++j){
if(j == 0){
cout<<trainNum[i][j];
}//if
else{
cout<<" "<<trainNum[i][j];
}//else
}//for
cout<<endl;
}//for
}//while
return 0;
}
C++ HOJ 火车进站的更多相关文章
- 华为OJ:火车进站
火车进站 给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号. 输入描述: 有多组测试用例, ...
- (hdu)1022 Train Problem I 火车进站问题
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1022 Problem Description As the new term comes, ...
- CodeVS3958 火车进站
3958 火车进站 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description 火车站内往往设有一些主干线分叉出去的铁路支路 ...
- HDU 1022 火车进站【栈】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1022 题目大意: 题目大概意思:有N辆火车,以序列1方式进站,判断是否能以序列2方式出栈.进站不一定 ...
- 华为OJ—火车进站(栈,字典排序)
http://career-oj.huawei.com/exam/ShowSolution?method=SolutionApp&id=2282 给定一个正整数N代表火车数量,0<N&l ...
- poj 1363 火车进站 (栈的应用)
Description There is a famous railway station in PopPush City. Country there is incredibly hilly. Th ...
- 火车进站输出路径(HDU1022)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1022 解题报告: 思路: 就是维护好这个栈,只要它不是空,并且头部和ans相同,就一直出栈,直到不满足 ...
- 火车安排问题(dp好题)
火车站内往往设有一些主干线分叉出去的铁路支路,供火车停靠,以便上下客或装载货物.铁路 支路有一定长度:火车也有一定的长度,且每列火车的长度相等. 假设某东西向的铁路上,有一小站.该站只有一条铁路支路可 ...
- HDU 1022(火车过站 栈)
题意是给定火车进站的序列和出站的序列,问能否完成转换,若能输出过程. 和另一道以火车进站为背景的栈应用题类似,但增加了对于过程的输出,只需要多记录一下进出站顺序即可. #include <bit ...
随机推荐
- spring中quartz的使用。【转http://www.cnblogs.com/kay/archive/2007/11/02/947372.html】
注:从spring3到spring4改变 org.springframework.scheduling.quartz.CronTriggerBean org.springframework.sched ...
- 【java小工具】从.java文件中筛选出方法,并计算出方法在这些文件中出现的次数
package getMethod; import java.io.*; import java.util.*; import java.util.regex.Matcher; import java ...
- net8:简易的文件磁盘管理操作一(包括文件以及文件夹的编辑创建删除移动拷贝重命名等)
原文发布时间为:2008-08-07 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...
- SGU101 求有重边的无向图欧拉迹
题意:好多木棒,俩端有数字(0--6)标记,按数字相同的端首尾相连成一条直线(木棒可以相同).即求有重边的无向图欧拉迹. 先判定是否为欧拉图,俩个条件,不说了.如果是欧拉图,输出路经. 方法:dfs遍 ...
- Python 和 Elasticsearch 构建简易搜索
Python 和 Elasticsearch 构建简易搜索 作者:白宁超 2019年5月24日17:22:41 导读:件开发最大的麻烦事之一就是环境配置,操作系统设置,各种库和组件的安装.只有它们都正 ...
- openssl搭建双向认证https
http://www.barretlee.com/blog/2015/10/05/how-to-build-a-https-server/ http://blog.163.com/fangjinbao ...
- 《Java虚拟机原理图解》1.4 class文件中的字段表集合--field字段在class文件中是怎样组织的
0.前言 了解JVM虚拟机原理是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述 ...
- [转]Linux上程序执行的入口--Main
main()函数,想必大家都不陌生了,从刚开始写程序的时候,大家便开始写main(),我们都知道main是程序的入口.那main作为一个函数,又是谁调用的它,它是怎么被调用的,返回给谁,返回的又是什么 ...
- fuel 安装openstack
- TFTP服务器
为什么要学习有关TFTP服务器的安装及配置呢?主要是为了后续学习有关linux系统的无人值守安装做准备. TFTP简单文件传输协议,使用UDP的69端口.主要提供文件的上传和下载,TFTP一般是适用于 ...