PAT团体程序设计天梯赛GPLT
火车站的列车调度铁轨的结构如下图所示。
两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?
输入格式:
输入第一行给出一个整数N (2 ≤ N ≤10
5
),下一行给出从1到N的整数序号的一个重排列。数字间以空格分隔。
输出格式:
在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。
输入样例:
9
8 4 2 5 3 9 1 6 7
输出样例:
4
// L2014 列车调度.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<stdio.h>
int main(int argc, char* argv[])
{
//int a[9]={8,4,2,5,3,9,1,6,7};
int a[9]={9,1,6,7,8,4,2,5,3};
int count=0;int cishu=0;
for(int i=0;i<8;i++){
//for(int i=0;i<8&&a[i]!=-1;i++){复合条件学的不好,慎用这样a[i]!=-1跳出外层循环
if(a[i]==-1)continue;//这样进入循环a[i]==-1,结束本次循环,进入下轮循环
int temp=a[i];
// flag=0;
for(int j=i+1;j<9;j++)
{
if(a[j]==-1)continue;
if(temp<a[j])
{
//int t=a[j];a[j]=temp;temp=t;
temp=a[j];
a[j]=-1;
//pos=j;
// flag=1;
}
}
a[i]=-1;//刚开始这句忘写了
count=0;
for(int k=0;k<9;k++)//计数最简单
{
if(a[k]==-1)
{
count++;
}
printf("%d ",a[k]);
}
printf("=====\n");
if(count<=9)
{++cishu; printf("cishu-------%d\n",cishu);}
else{
break;//跳出外层循环
}
// if(flag==0)break;
//count=0;
}
printf("Hello World!\n");
// printf("%d\n",cishu);
return 0;
}
反思:(1)count<9,则继续进行循环;当第一次count==9时 最后1次执行cishu++;else break退出循环
(2)循化中使用计数器,注意有的计数器要在适当的地方清0,例如count
(3)当要删除一个数时,我们可以用标记数组初始为0,对应的数被修改,则标记数组对应位置为1
(4)删除一个数,可以标记为特殊值,例如-1,当为-1说明已经删除
(5)for的条件中,复合语句我学的不是很好,容易错,先不用复合条件判断
(6)注意数组边界,j=i+1,数组中9个数,所以i<8
(7)程序中continue,用的很好,我以前没有这样用(亮点)
(8)程序的不到想要的结果,可以加断点调试或打印中间结果
上面的程序,利用count计数,count<9,则继续进行循环;当第一次count==9时 最后1次执行cishu++;else break退出循环
下面借用标志位flag
#include "stdafx.h"
#include<stdio.h>
int main(int argc, char* argv[])
{
//int a[9]={8,4,2,5,3,9,1,6,7};
int a[9]={9,1,6,7,8,4,2,5,3};
int count=0;int cishu=0;int flag=0;
for(int i=0;i<8;i++)
{
//for(int i=0;i<8&&a[i]!=-1;i++){复合条件学的不好,慎用这样a[i]!=-1跳出外层循环
if(a[i]==-1)continue;//这样进入循环a[i]==-1,结束本次循环,进入下轮循环
int temp=a[i];
flag=0;
for(int j=i;j<9;j++)//先自身与自身比,依次往后(j==i,和下面if(temp<=a[j]):用了小于等于)
{
if(a[j]==-1)continue;
if(temp<=a[j])//首先将a[i]==-1,依次往后
{
temp=a[j];//如果较大保存
a[j]=-1;//覆盖a[j]
flag=1;//标志位被修改
}
}
// a[i]=-1;//刚开始这句忘写了
/* count=0;
for(int k=0;k<9;k++)//计数最简单
{
if(a[k]==-1)
{
count++;
}
printf("%d ",a[k]);
}
printf("=====\n");
// if(count<=9)
// {++cishu; printf("cishu-------%d\n",cishu);}
// else{
// break;//跳出外层循环
// }*/
if(flag==1)
{
++cishu;
// printf("cishu-------%d\n",cishu);//test
}
else if(flag==0) break;
//count=0;
}
printf("Hello World!\n");
printf("%d\n",cishu);
return 0;
}
重点(1)
int temp=a[i];
flag=0;
//先自身与自身比,依次往后(j==i,和下面if(temp<=a[j]):用了小于等于)
for(int j=i;j<9;j++)
{
if(a[j]==-1)continue;
if(temp<=a[j])//首先将a[i]==-1,依次往后
{
temp=a[j];//如果较大保存
a[j]=-1;//覆盖a[j]
flag=1;//标志位被修改
}
}
j=i;(j的起点从i开始)//在for循环要格外注意初始值andand边界
if(temp<=a[j])//因为j=i;先自己比较肯定相等(这个重点1:是亮点)
重点(2)
if(flag==1)
{
++cishu;
// printf("cishu-------%d\n",cishu);//test
}
else if(flag==0) break;
flag被修改说明本趟进行了修改,需要计数,flag=0说明没被修改(标志位是循环常用知识点)