一.杨辉三角形
【问题描述】杨辉三角形的打印,请用循环队列实现。不采用“循环队列”,不给分。
【样例输入】
4
【样例输出】1
1 1
1 2 1
1 3 3 1
#include <iostream>
#define M 50
using namespace std;
typedef struct
{
int elem[M];
int front;
int rear;
}seqQueue,*Queue;
Queue InitQueue()
{
Queue q;
q=new seqQueue;
if(q==NULL)
{return NULL;
}
q->front=q->rear=0;
return q;
}
void enterqueue(Queue q,int x)
{
if((q->rear+1)%M==q->front)
{
return ;
}
q->elem[q->rear]=x;
q->rear=(q->rear+1)%M;
}
int outputqueue(Queue q)
{
int x;
if(q->rear==q->front)
return 0;
x=q->elem[q->front];
q->front=(q->front+1)%M;
return x;
}
int main()
{
Queue q;
int x=1,n;
cin>>n;
q=InitQueue();
for(int i=0;i<n;i++)
{
if(i==0)
{
cout<<1<<endl;
enterqueue(q,x);
}
else {
int a=0,b=0;
for(int k=0;k<i;k++)
{
a=b;
b=outputqueue(q);
x=a+b;
enterqueue(q,x);
cout<<x<<" ";
}
cout<<1<<endl;
x=1;
enterqueue(q,x);
}
}
return 0;
}
二. 队列元素逆置
【问题描述】已知Q是一个非空队列,S是一个空栈。仅使用少量工作变量以及对队列和栈的基本操作,编写一个算法,将队列Q中的所有元素逆置。需采用链式队列与栈(顺序或链式),否则不能得分。
【输入形式】输入的第一行为队列元素个数,第二行为队列从首至尾的元素
【输出形式】输出队列的逆置
【样例输入】
3
1 2 3
【样例输出】
3 2 1
#include <iostream>
using namespace std;
typedef struct node
{
int data;
node* next;
}node,*Stack;
Stack Init()
{
Stack s=new node;
s->next=NULL;
return s;
}
void push(Stack s,int n)
{
Stack t=new node;
t->data=n;
t->next=s->next;
s->next=t;
}
void pop(Stack s)
{
Stack p;
int top;
p=s->next;
s->next=p->next;
top=p->data;
cout<<top<<" ";
}
int obtain(Stack s)
{
return s->next->data;
}
int main()
{
int x,p;
Stack s=Init();
cin>>x;
for(int i=0;i<x;i++)
{
cin>>p;
push(s,p);
}
for(int j=x;j>0;j--)
{
pop(s);
}
return 0;
}
三.银行排队——队列
【问题描述】
我们大多都有在银行排队的经历,唉,那坑爹的排队啊!现在就让我们来算算我们这些客户平均需要等多久吧。
每天刚开始时银行会开m个窗口来为我们total个客户办理业务,当有客户需要办理业务时,先选择可以办理业务的窗口,如果有多个窗口可以办理业务就选择空闲时间最长的窗口,如果有多个窗口空闲的时间一样长,则选择序号小的窗口办理业务。假设我们每个人来到的时间和办理业务所需要的时间(为了简化问题,采用整数表示时间)都知道了。现在请你算算我们平均需要等待多久呢?请用顺序队列或链式队列来完成本题。【输入形式】
有多组测试数据,每组数据开始有两个正整数m(<20)和total(<200),后面有total对整数,对应客户先后到来的时间以及办理业务所需的时间。
【输出形式】
平均等待的时间,保留两位小数。
【样例输入】
2 6 1 3 4 1 5 3 9 2 13 4 13 3
3 14 0 3 2 2 2 4 5 4 7 2 11 3 12 3 12 4 12 1 13 3 15 4 19 1 22 3 23 2
2 5 0 6 0 5 0 6 7 1 7 2【样例输出】
0.00
0.29
1.20【提示】
题目中选择办理的窗口有三个状态,实际上从序号自小到大查找可以最早办理业务的窗口就已经满足上述三个状态了。若客户的到来时间相同,现实中并不知道该用户需要多久处理完任务,所以遵循先来的先服务原则。
【要求】
请用顺序队列或链式队列来完成,否则不得分。
这道题水了一下,并没有用队列来做,经供参考。
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
int m, t;
while (cin>>m>>t)
{
int a, b;
int sum = 0;
int q[20]={0};
for (int i = 0; i < t; i++)
{
cin >> a >> b;
int arr = 0;
int Min = q[0];
for (int i = 0; i < m; i++)
{
if (q[i] <Min)
{
Min = q[i];
arr = i;
}
}
if (a < q[arr])
{
sum += (q[arr] - a);
q[arr] += b;
}
else
{
q[arr] = a + b;
}
}
printf("%.2f\n", sum*1.0/t);
}
return 0;
}
四.整数划分问题
【问题描述】根据课堂讲授,编程实现某整数的划分的输出
【样例输入】
6
【样例输出】6
5+1
4+2
4+1+1
3+3
3+2+1
3+1+1
2+2+2
2+2+1+1
2+1+1+1+1
1+1+1+1+1+1
这道题使用了深度优先搜索,即dfs,作者本人也是初学者;
#include <iostream>
using namespace std;
int mark[100];
int n;
void dfs(int sum,int k,int x);
int main()
{
cin>>n;
dfs(0,0,n);
return 0;
}
void dfs(int sum,int k,int x)
{
if(sum>n)return ;
else if(sum==n)
{
for(int i=0;i<k-1;i++)
{cout<<mark[i]<<"+";}
cout<<mark[k-1]<<endl;
}
else {
for(int j=x;j>=1;j--)
{
mark[k]=j;
sum+=j;
dfs(sum,k+1,j);
sum-=j;
}
}
}
第五题和第六题都是有关卡特兰数的题,近期会写有关博文。
五. 买票问题——卡特兰数
【问题描述】
m个人只有50元钱,n个人只有100元整钱,票价50元/人。现在售票厅没钱,只有50元钱的人可以不用找钱顺利买票,而拿着100元整钱的人只有在前面有50元的情况下才能买票,因为只有这样,才能找零50元。所有的人能否买票和排队的方式有一定关系,问使得所有的人能够顺利买票的排队方式有多少种?
【输入形式】
m和n,当输入0 0则结束输入
【输出形式】
先输出:Test #i:期中i代表第几组测试数据;再输出排队方式的种数
【样例输入】
3 0
3 1
3 3
0 0
【样例输出】
Test #1:
6
Test #2:
18
Test #3:
180
#include <iostream>
using namespace std;
int main()
{
long long n,m,i=0,sum=1;
while(1)
{ cin>>m>>n;
if(n==0&&m==0)
break;
else
{
i++;
for(int i=1;i<=m+n;i++)
sum*=i;
sum=sum*(m+1-n)/(m+1);
cout<<"Test #"<<i<<":"<<endl;
cout<<sum<<endl;
sum=1;
}
}
}
六. 小兔的棋盘——卡特兰数
【问题描述】
小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧!
【输入形式】
每次输入一个数n(1<=n<=35),当n等于-1时结束输入。
【输出形式】
对于每个输入数据输出路径数,具体格式看Sample。
【样例输入】
1
3
12
-1
【样例输出
1 1 2
2 3 10
3 12 416024
#include <iostream>
using namespace std;
int main()
{ int f[40]={0};
int n,num=0, m;
f[0]=1,f[1]=1;
for(int i=2;i<=39;i++)
for(int j=0;j<i;j++)
f[i]+=f[j]*f[i-j-1];
while(1)
{
cin>>n;
if(n==-1)
break;
num++;
m=f[n]*2;
cout<<num<<" "<<n<<" "<<m<<endl;
}
}