铁轨(poj 1363)
某城市有一个火车站,其中的铁路如图:

每辆火车都从A方向驶入车站,再从B方向驶出车站,同时它的车厢可以进行某种形式的重新组合。假设从A方向驶来的火车有n节车厢(n<=1000),分别按顺序编号为:1、2…,n。假定在进入车站之前每节车厢之间都是不连着的,并且它们可以自行移动,直到处在B方向的铁轨上。另外假定车站C里可以停放任意多节的车厢。但是一旦当一节车厢进入车站C ,它就不能再回到A方向的铁轨上了,并且一旦它进入B的方向的铁轨后,它就不能再回到车站C。
负责车厢调度的工作人员需要知道能否使他以a1,a2,a2……,an的顺序从B方向驶出,请写一个程序,用来判断能否得到指定的车厢顺序。
分析:用栈模拟车站C,用x标记A方向将要驶出的车厢,用y标记B方向下一辆要驶入的车厢。
if(x等于y)
直接开过去
else if(x小于y)
将x入栈直到x>y
else If(x大于y)
从栈里驶出,如果栈里的车厢不等于y那就表示无解
代码:
#include <stack>
using namespace std;
int main()
{
int n,i;
int a[1001];
int coach;
stack<int> s;
while(1)
{
scanf("%d",&n);
if(n==0) break;
while(1)
{
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[0]==0) break;
}
if(a[0]==0) break;
while(!s.empty()) s.pop();
coach=1;
for(i=0;i<n;i++)
{
if(a[i]==coach)
coach++;
else if(a[i]>coach)
{
while(a[i]>coach)
{
s.push(coach);
coach++;
}
coach++;
}
else if(a[i]<coach)
{
if(a[i]!=s.top())
{
printf("No\n");
break;
}
s.pop();
}
}
if(i>=n)
printf("Yes\n");
}
printf("\n");
}
return 0;
}
小球钟——时间与运动(poj 1879)
分析(取自黑书):模拟小球钟的运作,分钟、5分钟、小时轨道符合“后进先出”的特点,是栈。而底部的轨道符合“先进先出”的特点,构成了一个队列。我们先模拟一天的状态,将小球编号1,2,3…n,然后得到一天后新小球队列P1,P2,…Pn。我们得到一种置换F(1,2,…,n)=(P1,P2,…,Pn)。有了这个条件,对于当前处在x位置上的小球,无论小球编号多少,都知道它再过24小时应当处于位置Px,我们可以求出每一个小球回到原来位置的周期,然后求所有小球周期的最小公倍数。
代码:
using namespace std;
typedef int type;
const int Max_Size=1000;
class Queue{
private:
type queue[Max_Size];
int rear, front, Size;
public:
Queue(){
rear = front = -1;
Size = 0;
}
void enqueue( type data ) {
rear = ( rear + 1 ) % Max_Size;
queue[ rear ] = data;
++ Size;
}
type dequeue() {
front = ( front + 1 ) % Max_Size;
-- Size;
return queue[ front ];
}
bool empty(){
return !Size;
}
int size(){
return Size;
}
};
class Stack{
private:
type stack[Max_Size];
int top;
public:
Stack(){
top = 0;
}
void push( type data ){
if ( top < Max_Size ){
stack[ top ++ ] = data;
}
else{
cout << "No Enough Space!" << endl;
}
}
type pop(){
if ( top ){
return stack[ -- top ];
}
else{
cout << "No Element Now!" << endl;
return 0;
}
}
bool empty(){
return !top;
}
int size(){
return top;
}
};
int gcd(int a,int b)
{
int t,c;
if(a==0)
return b;
if(b==0)
return a;
if(a<b)
t=a,a=b,b=t;
for(c=a%b;c>0;c=a%b)
{
a=b;b=c;
}
return b;
}
int main()
{
Queue bottom;
Stack min,fivemin,hour;
int a,b,i,j,n;
int pos[1001],cycle[1001];
while(1){
scanf("%d",&n);
if(n==0) break;
while(!bottom.empty()) bottom.dequeue();
while(!min.empty()) min.pop();
while(!fivemin.empty()) fivemin.pop();
while(!hour.empty()) hour.pop();
for(i=1;i<=n;i++) bottom.enqueue(i);
int day=24*60;
for(i=0;i<day;i++){
a=bottom.dequeue();
if(min.size()==4){
for(j=0;j<4;j++){
b=min.pop();
bottom.enqueue(b);
}
if(fivemin.size()==11){
for(j=0;j<11;j++){
b=fivemin.pop();
bottom.enqueue(b);
}
if(hour.size()==11){
for(j=0;j<11;j++){
b=hour.pop();
bottom.enqueue(b);
}
bottom.enqueue(a);
}
else
hour.push(a);
}
else
fivemin.push(a);
}
else
min.push(a);
}
for(i=1;i<=n;i++)
pos[i]=bottom.dequeue();
for(i=1;i<=n;i++)
cycle[i]=1;
int k;
for(i=1;i<=n;i++){
k=pos[i];
while(i!=k){
k=pos[k];
cycle[i]++;
}
}
int sum=1;
for(i=1;i<=n;i++){
sum=sum*cycle[i]/gcd(sum,cycle[i]);
}
printf("%d balls cycle after %d days.\n",n,sum);
}
return 0;
}
直接用STL,会比较慢,而且调试不方便,所以就自己写队列和栈。
队列的模板:
#include <iomanip>
using namespace std;
typedef int type;
const int Max_Size = 10;
class Queue{
private:
type queue[Max_Size];
int rear, front, Size;
public:
Queue(){
rear = front = -1;
Size = 0;
}
void enqueue( type data ) {
rear = ( rear + 1 ) % Max_Size;
queue[ rear ] = data;
++ Size;
}
type dequeue() {
front = ( front + 1 ) % Max_Size;
-- Size;
return queue[ front ];
}
bool empty(){
return !Size;
}
int size(){
return Size;
}
};
int main(){
Queue T;
int i;
for ( i = 1; i <= 8; ++ i ){
T.enqueue(i);
}
while ( !T.empty() ){
cout << setw(4) << T.dequeue();
}
cout << endl;
for ( i = 9; i <= 18; ++ i ){
T.enqueue(i);
}
cout << "Size = " << T.size() << endl;
while ( !T.empty() ){
cout << setw(4) << T.dequeue();
}
cout << endl;
system("PAUSE");
return 0;
}
栈的模板:
// Written By Alphard
// Date : 2008.4.27
#include <iostream>
#include <iomanip>
using namespace std;
typedef int type;
const int Max_Size = 1000;
class Stack{
private:
type stack[Max_Size];
int top;
public:
Stack(){
top = 0;
}
void push( type data ){
if ( top < Max_Size ){
stack[ top ++ ] = data;
}
else{
cout << "No Enough Space!" << endl;
}
}
type pop(){
if ( top ){
return stack[ -- top ];
}
else{
cout << "No Element Now!" << endl;
}
}
bool empty(){
return !top;
}
int size(){
return top;
}
};
int main(){
Stack T;
int i;
for ( i = 1; i <= 8; ++ i ){
T.push(i);
}
while ( !T.empty() ){
cout << setw(4) << T.pop();
}
cout << endl;
system("PAUSE");
return 0;
}
求最大公约数的模板:
{
int t,c;
if(a==0)
return b;
if(b==0)
return a;
if(a<b)
t=a,a=b,b=t;
for(c=a%b;c>0;c=a%b)
{
a=b;b=c;
}
return b;
}

