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 ...
随机推荐
- P1681 最大正方形II (动态规划)
题目背景 忙完了学校的事,v神终于可以做他的"正事":陪女朋友散步.一天,他和女朋友走着走着,不知不觉就来到了一个千里无烟的地方.v神正要往回走,如发现了一块牌子,牌子上有有一行小 ...
- 转载: LINK : fatal error LNK1104: 无法打开文件“mfc71.lib”的原因又一例
转载地址:http://blog.csdn.net/mxclxp/article/details/8196142 LINK : fatal error LNK1104: 无法打开文件“mfc71.li ...
- 路飞学城详细步骤 part1
详细步骤 1 添加登录页面 步骤: Header.vue 写一个登录按钮,<router-link to = ' /xx'> 在路由的 index.js中添加这个 新的路由,{'path' ...
- VMware---之网卡设置
闲来无事,扯点皮,详细说下NAT配置过程 NAT全称Network Address Translation网络地址转换,顾名思义,配置的重点也是地址转换. 步骤1.配置局域网段及网关 打开vmware ...
- 洛谷 [P1290] 欧几里得的游戏
SG函数的应用 看到这题就想到了SG函数 那么可以考虑最终情况:一个数是x,另一个是0,那么先手必败(因为上一个人已经得到0了,其实游戏已经结束了) 剩下的情况:一个数n, 一个数m,假设n>m ...
- ElasticSearch聚合入门(续)
主要理解聚合中的terms. 参考:http://www.cnblogs.com/xing901022/p/4947436.html Terms聚合 记录有多少F,多少M { "size&q ...
- BZOJ4723: [POI2017]Flappy Bird
$n \leq 500000$个水管,每秒横坐标加一,纵坐标如果你点击就+1否则-1,问从$(0,0)$飞到$m$处最少点多少次,或者说明无解. 如果能飞到某个水管的高度区间$[L,R]$,那么答案肯 ...
- ci框架——数据库(增删改查)
1:配置数据库(application/config/database.php)修改 $db['default'] = array( 'dsn' => '', 'hostname' => ...
- spring boot -- 无法读取html文件,碰到的坑
碰到的坑,无法Controller读取html文件 1. Controller类一定要使用@Controller注解,不要用@RestController 2. resource目录下创建templa ...
- Easy sssp(spfa)(负环)
vijos 1053 Easy sssp 方法:用spfa判断是否存在负环 描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,00 ...