7-1 银行业务队列简单模拟
设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。
输入格式:
输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。
输出格式:
按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。
输入样例:
8 2 1 3 9 4 11 13 15
输出样例:
1 3 2 9 11 4 13 15
#include<stdio.h>
int main()
{
int n,m,i;
int a[10086],b[10086],c[10086];
int ji=0,ou=0,x=0,y=0,index=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&m);
if(m%2!=0)
{
a[ji++]=m;
}
else
{
b[ou++]=m;
}
}
while(x<ji||y<ou)
{
if(x<ji)
{
c[index++]=a[x];
}
if(x+1<ji)
{
c[index++]=a[x+1];
}
x=x+2;
if(y<ou)
{
c[index++]=b[y];
}
y=y+1;
}
for(i=0;i<index;i++)
{
if(i==0)
printf("%d",c[i]);
else
printf(" %d",c[i]);
}
return 0;
}
7-2 表达式转换
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+
、-
、*
、/
以及左右括号()
,表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
#include<stdio.h>
#include<string.h>
void print()
{
static int flag=0;
if(flag!=0)
putchar(' ');
flag++;
}
int main()
{
char stack[10086];
char str[10086];
int top=-1,i;
gets(str);
int len=strlen(str);
for(i=0;i<len;i++)
{
if((str[i]=='+'||str[i]=='-')&&(i==0||str[i-1]=='(')||isdigit(str[i]))
{
print();
if(str[i]!='+')
putchar(str[i]);
while(str[i+1]=='.'||isdigit(str[i+1]))
putchar(str[++i]);
}
else
{
if(str[i]==')')
{
while(top!=-1&&stack[top]!='(')
{
print();
putchar(stack[top--]);
}
if(top!=-1)
{
top--;
}
}
else
{
if(top==-1)
{
stack[++top]=str[i];
}
else
{
while(top>-1&&stack[top]!='(')
{
if(str[i]=='('||((str[i]=='*'||str[i]=='/')&&(stack[top]=='+'||stack[top]=='-')))
{
break;
}
print();
putchar(stack[top--]);
}
stack[++top]=str[i];
}
}
}
}
while(top>-1)
{
if(stack[top]=='(')
top--;
else
print();
putchar(stack[top--]);
}
return 0;
}
7-3 堆栈模拟队列
设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。
所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数:
int IsFull(Stack S)
:判断堆栈S
是否已满,返回1或0;int IsEmpty (Stack S )
:判断堆栈S
是否为空,返回1或0;void Push(Stack S, ElementType item )
:将元素item
压入堆栈S
;ElementType Pop(Stack S )
:删除并返回S
的栈顶元素。
实现队列的操作,即入队void AddQ(ElementType item)
和出队ElementType DeleteQ()
。
输入格式:
输入首先给出两个正整数N1
和N2
,表示堆栈S1
和S2
的最大容量。随后给出一系列的队列操作:A item
表示将item
入列(这里假设item
为整型数字);D
表示出队操作;T
表示输入结束。
输出格式:
对输入中的每个D
操作,输出相应出队的数字,或者错误信息ERROR:Empty
。如果入队操作无法执行,也需要输出ERROR:Full
。每个输出占1行。
输入样例:
3 2
A 1 A 2 A 3 A 4 A 5 D A 6 D A 7 D A 8 D D D D T
输出样例:
ERROR:Full
1
ERROR:Full
2
3
4
7
8
ERROR:Empty
#include<stdio.h>
int main()
{
int n1,n2,x;
int max,min;
char c;
scanf("%d %d",&n1,&n2);
if(n1>n2)
{
max=n1;
min=n2;
}
else
{
min=n1;
max=n2;
}
int s1[min],s2[max];
int top1=0,top2=0;
getchar();
while(scanf("%c",&c)&&c!='T')
{
if(c=='A')
{
scanf("%d",&x);
if(top1<min)
s1[top1++]=x;
else
{
if(top2==0)
{
while(top1!=0)
{
s2[top2++]=s1[--top1];
}
s1[top1++]=x;
}
else
{
printf("ERROR:Full\n");
}
}
}
if(c=='D')
{
if(top2!=0)
{
printf("%d\n",s2[--top2]);
}
else
{
if(top1!=0)
{
while(top1!=0)
{
s2[top2++]=s1[--top1];
}
printf("%d\n",s2[--top2]);
}
else
printf("ERROR:Empty\n");
}
}
}
return 0;
}
7-4 输出全排列
请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间。
输入格式:
输入给出正整数n(<10)。
输出格式:
输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1,a2,⋯,an排在序列b1,b2,⋯,bn之前,如果存在k使得a1=b1,⋯,ak=bk 并且 ak+1<bk+1。
输入样例:
3
输出样例:
123
132
213
231
312
321
#include<stdio.h>
int a[10086],b[10086];
void quanpai(int n,int len)
{
if(n==len)
{
for(int i=1;i<=n;i++)
{
printf("%d",a[i]);
}
printf("\n");
}
else
{
for(int k=1;k<=n;k++)
{
if(b[k]==0)
{
a[len+1]=k;
b[k]=1;
quanpai(n,len+1);
b[k]=0;
}
}
}
}
int main()
{
int n;
scanf("%d",&n);
quanpai(n,0);
return 0;
}
7-5 括号匹配
给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配。
输入格式:
输入在一行中给出一行字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。
输出格式:
如果括号配对,输出yes,否则输出no。
输入样例1:
sin(10+20)
输出样例1:
yes
输入样例2:
{[}]
输出样例2:
no
#include<stdio.h>
int top=-1;
char stack[10086];
void push(char x)
{
stack[++top]=x ;
}
char pop()
{
if(top==-1)
return 0;
else
return stack[top--];
}
int peidui(char str[])
{
int i=0;
while(str[i]!='\0')
{
if(str[i]=='('||str[i]=='{'||str[i]=='[')
push(str[i]);
else if(str[i]==')'||str[i]=='}'||str[i]==']')
{
if(top==-1||str[i]-pop()>2)
return 0;
}
i=i+1;
}
return(top==-1);
}
int main()
{
char str[10086];
fgets(str,sizeof(str),stdin);
if(peidui(str))
printf("yes");
else
printf("no");
return 0;
}
7-6 出栈序列的合法性
给定一个最大容量为 m 的堆栈,将 n 个数字按 1, 2, 3, ..., n 的顺序入栈,允许按任何顺序出栈,则哪些数字序列是不可能得到的?例如给定 m=5、n=7,则我们有可能得到{ 1, 2, 3, 4, 5, 6, 7 },但不可能得到{ 3, 2, 1, 7, 5, 6, 4 }。
输入格式:
输入第一行给出 3 个不超过 1000 的正整数:m(堆栈最大容量)、n(入栈元素个数)、k(待检查的出栈序列个数)。最后 k 行,每行给出 n 个数字的出栈序列。所有同行数字以空格间隔。
输出格式:
对每一行出栈序列,如果其的确是有可能得到的合法序列,就在一行中输出YES
,否则输出NO
。
输入样例:
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
输出样例:
YES
NO
NO
YES
NO
#include<stdio.h>
int main()
{
int stack[10086];
int b[10086];
int m,n,k;
int flag,top;
scanf("%d %d %d",&m,&n,&k);
while(k--)
{
int index1=1,index2=0;
flag=1;
top=-1;
for(int i=0;i<n;i++)
{
scanf("%d",&b[i]);
}
while(index2<n)
{
if(top!=-1&&stack[top]==b[index2])
{
top--;
index2++;
}
else
{
stack[++top]=index1++;
if(top>=m)
{
flag=0;
break;
}
}
}
if(flag==0||top!=-1)
printf("NO\n");
else
printf("YES\n");
}
return 0;
}
7-7 后缀式求值
我们人类习惯于书写“中缀式”,如 3 + 5 * 2
,其值为13
。 (p.s. 为什么人类习惯中缀式呢?是因为中缀式比后缀式好用么?)
而计算机更加习惯“后缀式”(也叫“逆波兰式”,Reverse Polish Notation)。上述中缀式对应的后缀式是: 3 5 2 * +
现在,请对输入的后缀式进行求值。
输入格式:
在一行中输入一个后缀式,运算数
和运算符
之间用空格分隔,运算数长度不超过6
位,运算符仅有+ - * /
四种。
输出格式:
在一行中输出后缀式的值,保留一位小数。
输入样例:
3 5.4 2.2 * +
输出样例:
14.9
#include<stdio.h>
int main()
{
char str[10086];
double st[10086];
int i;
while(scanf("%s",str)!=EOF)
{
if(str[1]=='\0'&&(str[0]=='+'||str[0]=='-'||str[0]=='*'||str[0]=='/'))
{
double num1,num2,current;
num1=st[--i];
num2=st[--i];
switch(str[0])
{
case'+':current=num2+num1;st[i++]=current;break;
case'-':current=num2-num1;st[i++]=current;break;
case'*':current=num2*num1;st[i++]=current;break;
case'/':current=num2/num1;st[i++]=current;break;
}
}
else
{
double num;
sscanf(str,"%lf",&num);
st[i++]=num;
}
}
printf("%.1f",st[0]);
}
7-8 进制转换
输入十进制整数N和待转换的进制x(2、8、16),分别代表十进制N转换成二进制、八进制和十六进制,输出对应的结果。十六进制中A~F用大写字母表示。
输入格式:
输入两个整数N(十进制整数N)和x(x进制),中间用空格隔开。
输出格式:
输出对应的结果。
输入样例:
在这里给出一组输入。例如:
123 2
输出样例:
在这里给出相应的输出。例如:
1111011
#include<stdio.h>
int main()
{
int n,x,a,b;
int i=1;
scanf("%d %d",&n,&x);
if(x==2)
{
while(n!=0)
{
a=n%2;
n=n/2;
b=b+i*a;
i=i*10;
}
printf("%d",b);
}
else if(x==8)
{
printf("%o",n);
}
else if(x==16)
{
char str[10086];
sprintf(str,"%X",n);
printf("%s",str);
}
return 0;
}
7-9 行编辑器
一个简单的行编辑程序的功能是:接受用户从终端输入的程序或数据,并存入用户的数据区。
由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的。较好的做法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区。允许用户输入出差错,并在发现有误时可以及时更正。例如,当用户发现刚刚键入的一个字符是错的时,可补进一个退格符"#",以表示前一个字符无效;
如果发现当前键入的行内差错较多或难以补救,则可以键入一个退行符"@",以表示当前行中的字符均无效。
如果已经在行首继续输入'#'符号无效。
输入格式:
输入一个多行的字符序列。但行字符总数(包含退格符和退行符)不大于250。
输出格式:
按照上述说明得到的输出。
输入样例1:
在这里给出一组输入。例如:
whli##ilr#e(s#*s)
输出样例1:
在这里给出相应的输出。例如:
while(*s)
输入样例2:
在这里给出一组输入。例如:
outcha@putchar(*s=#++);
输出样例2:
在这里给出相应的输出。例如:
putchar(*s++);
#include<stdio.h>
void bj(char input[])
{
int index=0;
char hc[10086];
for(int i=0;input[i]!='\0';i++)
{
if(input[i]=='#')
{
if(index>0)
{
index--;
}
}
else if(input[i]=='@')
index=0;
else
{
hc[index++]=input[i];
}
}
hc[index]='\0';
printf("%s",hc);
}
int main()
{
char input[10086];
fgets(input,sizeof(input),stdin);
input[strcspn(input,"\n")]='\0';
bj(input);
return 0;
}
7-10 选数
已知n个整数x1,x2,x3...xi,以及1个整数k(k<n)。从 n 个整数中任选 k个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4个整数分别为3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22,
3+7+19=29,
7+12+19=38,
3+12+19=34,
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29
输入格式:
第一行两个空格隔开的整数 n,k(1≤n≤20,k<n)
第二行n个整数,两数之间空格隔开(1≤xi≤1000000)
输出格式:
输出一个整数,表示种类数。
输入样例:
在这里给出一组输入。例如:
4 3
3 7 12 19
输出样例:
在这里给出相应的输出。例如:
1
#include<stdio.h>
int sum,t=0;
int a[10086],b[10086];
int k;
void fun(int n,int m)
{
int i;
if(m==0)
{
sum=0;
for(i=0;i<k;i++)
{
sum=sum+b[i];
}
if(sushu(sum))
{
t++;
}
}
else
{
for(i=n;i>=m;i--)
{
b[m-1]=a[i];
fun(i-1,m-1);
}
}
}
int sushu(int n)
{
int i;
if(n==2)
return 1;
for(i=2;i<=n-1;i++)
{
if(n%i==0)
break;
}
if(i==n)
return 1;
else
return 0;
}
int main()
{
int i,n;
scanf("%d %d",&n,&k);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
fun(n,k);
printf("%d\n",t);
return 0;
}