考核
笔试题目
- 递归过程或者函数调用时,处理参数及返回地址,要用一种称为栈的数据结构。
- 消除递归不一定要使用栈(√)
- 一颗二叉树的中序遍历为:DCBFAHGE,后序遍历为:DFBCGHEA,请画出这颗二叉树的图形:
首先再复习一下有关二叉树的一些东西:
前序遍历算法:
void PreOrderTraverse(BiTree T){
if(T==NULL)
return;
printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
PreOrderTraverse(T->lchild); /* 再先序遍历左子树 */
PreOrderTraverse(T->rchild); /* 最后先序遍历右子树 */
}
ABDHKECFIGJ
中序遍历算法:
void InOrderTraverse(BiTree T){
if(T==NULL)
return;
InOrderTraverse(T->lchild); /* 中序遍历左子树 */
printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
InOrderTraverse(T->rchild); /* 最后中序遍历右子树 */
}
HKDBEAIFCGJ
后序遍历算法:
void PostOrderTraverse(BiTree T){
if(T==NULL)
return;
PostOrderTraverse(T->lchild); /* 先后序遍历左子树 */
PostOrderTraverse(T->rchild); /* 再后序遍历右子树 */
printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
}
KHDEBIFJGCA
特别的:
接下来就显而易见了!
前序遍历:根左右
先序遍历可以想象成,小人从树根开始绕着整棵树的外围转一圈,经过结点的顺序就是先序遍历的顺序
中序遍历:左根右
中序遍历可以想象成,按树画好的左右位置投影下来就可以了
后序遍历:左右根
后序遍历就像是剪葡萄,我们要把一串葡萄剪成一颗一颗的。
还记得我们先序遍历绕圈的路线么?
就是围着树的外围绕一圈,如果发现一剪刀就能剪下的葡萄(必须是一颗葡萄),就把它剪下来,组成的就是后序遍历了。
以上参考:一位大佬生动形象的讲解,大家可以参考一下
给定了二叉树的任何一种遍历序列,都无法唯一确定相应的二叉树。但是如果知道了二叉树的中序遍历序列和任意的另一种遍历序列,就可以唯一地确定二叉树。
题目:一颗二叉树的中序遍历为:DCBFAHGE,后序遍历为:DFBCGHEA,请画出这颗二叉树的图形:
小方法:
- 后序遍历序列的最后一个结点是根结点,所以可知A为根结点。
- 中序遍历序列的根结点在中间,其左边是左子树,右边是右子树。根结点A的左子树DCBF,右子树是HGE。
- 后序遍历里面,左右子树序列的最后一位都是二叉树的左结点和右结点。所以上面题目的左结点就是C,右结点是E
- 然后经过一系列操作
- 最后答案就出来啦!
还有一道关于图的问题:
分别用邻接矩阵和邻接表来表示它:
机试
第一题
一个结构体二级排序
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
struct node{
char id[10];
char name[10];
int fen;
}stu[100005];
int cmp1(node a,node b){
if(strcmp(a.id,b.id)<0){
return 1;
}else{
return 0;
}
}
int cmp2(node a,node b){
if(strcmp(a.name,b.name)<0){
return 1;
}
else if(strcmp(a.name,b.name)==0){
if(strcmp(a.id,b.id)<0){
return 1;
}
return 0;
}
return 0;
}
int cmp3(node a,node b){
if(a.fen<b.fen){
return 1;
}else if(a.fen==b.fen){
if(strcmp(a.id,b.id)<0){
return 1;
}
return 0;
}
return 0;
}
int main(){
int n,t;
int ans=0;
while(~scanf("%d%d",&n,&t)&&n&&t){
ans++;
for(int i=1;i<=n;i++){
cin>>stu[i].id>>stu[i].name>>stu[i].fen;
}
switch(t){
case 1:
sort(stu+1,stu+n+1,cmp1);
break;
case 2:
sort(stu+1,stu+n+1,cmp2);
break;
case 3:
sort(stu+1,stu+n+1,cmp3);
}
printf("Case %d:\n",ans);
for(int i=1;i<=n;i++ ){
cout<<stu[i].id<<" "<<stu[i].name<<" "<<stu[i].fen<<endl;
}
}
return 0;
}
第二题
去年蓝桥杯的题,恰巧之前做过,就是输入一个日期,求今天星期几
#include<stdio.h>
int a[14]={31,28,31,30,31,30,31,31,30,31,30,31};
int main(){
int y,m,d;
while(~scanf("%d%d%d",&y,&m,&d)){
if(y>0&&y<=10000&&m>=1&&m<=12&&d>=1&&d<=31){
int sum=0;
int flag=1;
for(int i=1;i<y;i++){
if((i%400==0)||((i%4==0)&&(i%100!=0))){
sum+=366;
}else{
sum+=365;
}
}
if((y%400==0)||((y%4==0)&&(y%100!=0))){
a[1]=29;
for(int j=0;j<m-1;j++){
sum+=a[j];
}
if(a[m-1]<d){
flag=0;
}
sum+=d;
}else{
a[1]=28;
for(int j=0;j<m-1;j++){
sum+=a[j];
}
if(a[m-1]<d){
flag=0;
}
sum+=d;
}
if(flag==0){
printf("illegal\n");
}else{
int m;
m=(sum%7);
switch(m){
case 1:
printf("Monday\n");
break;
case 2:
printf("Tuesday\n");
break;
case 3:
printf("Wednesday\n");
break;
case 4:
printf("Thursday\n");
break;
case 5:
printf("Friday\n");
break;
case 6:
printf("Saturday\n");
break;
case 0:
printf("Sunday\n");
break;
}
}
}
else{
printf("illegal\n");
}
}
return 0;
}
这道题最关键的是要把数据考虑全,比如2月31日是错误数据
第三题
后缀表达式(逆波兰)
用栈实现
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<stack>
#include<cstring>
#include<iomanip>//这个头文件可以实现c++的格式化输出
using namespace std;
int main(){
stack<double> S;
double a,b,x;
char ch[100];
while(scanf("%s",ch)!=EOF){
int len=strlen(ch);
if(len==1){
if(ch[0] == '+'){
a=S.top();S.pop();
b=S.top();S.pop();
S.push(a+b);
}
else if(ch[0] == '-'){
a=S.top();S.pop();
b=S.top();S.pop();
S.push(b-a);
}
else if(ch[0] == '*'){
a=S.top();S.pop();
b=S.top();S.pop();
S.push(a*b);
}
else if(ch[0] == '/'){
a=S.top();S.pop();
b=S.top();S.pop();
S.push(b/a);
}
else if(ch[0]=='-'&&(ch[1]>='0'||ch[1]<='9')){
a=atof(ch);
a=-a;
S.push(a);
}else{
a=atof(ch);
S.push(a);
}
}else{
a=atof(ch);
S.push(a);
}
}
printf("%.6lf\n",S.top());
return 0;
}
第四题
BFS
样例:
4 4
Y.#@
….
.#…
@…M
4 4
Y.#@
….
.#…
@#.M
5 5
Y…@.
.#…
.#…
@…M.
#…#
结果:
66
88
66
#include<iostream>
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
struct node{
int x;
int y;
int step;
};
int n,m;
int visit1[201][201],visit2[201][201],ans1[201][201],ans2[201][201];
int next[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
char map[201][201];
int check(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m&&map[x][y]!='#'){
return 1;
}
return 0;
}
void BFS(int ans[201][201],int visit[201][201],int x,int y){
int next[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int i;
queue<node> que;
node start,end;
start.x=x;
start.y=y;
start.step=0;
ans[x][y]=0;
visit[x][y]=1;
que.push(start);
while(!que.empty()){
start=que.front();
que.pop();
for(i=0;i<4;i++){
end.x=start.x+next[i][0];
end.y=start.y+next[i][1];
if(check(end.x,end.y)&&!visit[end.x][end.y]){
end.step=start.step+1;
ans[end.x][end.y]=end.step;
visit[end.x][end.y]=1;
que.push(end);
}
}
}
}
int main(){
int i,j,min,x1,x2,y1,y2;
while(scanf("%d%d",&n,&m)!=EOF){
for(i=0;i<n;i++){
scanf("%s",map[i]);
for(j=0;j<m;j++){
if(map[i][j]=='Y'){
x1=i;y1=j;
}
if(map[i][j]=='M'){
x2=i;y2=j;
}
}
}
memset(visit1,0,sizeof(visit1));
memset(ans1,0,sizeof(ans1));
BFS(ans1,visit1,x1,y1);
memset(visit2,0,sizeof(visit2));
memset(ans2,0,sizeof(ans2));
BFS(ans2,visit2,x2,y2);
min=9999999;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
if(map[i][j]=='@'&&visit1[i][j]&&visit2[i][j]){
min=min<(ans1[i][j]+ans2[i][j])?min:ans1[i][j]+ans2[i][j];
}
}
}
printf("%d\n",min*11);
}
return 0;
}
第五题
贪心
#include<stdio.h>
struct node{
int min;
int max;
}a[35];
int main(){
int d,sumtime;
int summin=0;
int summax=0;
scanf("%d%d",&d,&sumtime);
for(int i=1;i<=d;i++){
scanf("%d%d",&a[i].min,&a[i].max);
summin+=a[i].min;
summax+=a[i].max;
}
if(summin<=sumtime&&summax>=sumtime){
printf("YES\n");
for(int i=1;i<=d;i++){
while((a[i].max>a[i].min)&&(summax>sumtime)){
a[i].max--;
summax--;
}
}
for(int i=1;i<=d-1;i++){
printf("%d ",a[i].max);
}
printf("%d",a[d].max);
}else{
printf("NO\n");
}
return 0;
}