二叉树的创建
这里介绍一下递归的创建方式
先序创建:
struct note
{
int val;
struct note *left;
struct note *right;
};
typedef struct note SN;
void creat(SN *&a)
{
a=(SN *)malloc(sizeof(SN));
a->vol=val;
creat(a->left);
creat(a->right);
}
先序、中序、后序遍历输出:
void xian(SN *a)//先序遍历
{
if(a!=NULL)
{
cout<<a->val<<' ';
xian(a->left);
xian(a->right);
}
}
void zhong(SN *a)//中序遍历
{
if(a)
{
zhong(a->left);
cout<<a->val<<' ';
zhong(a->right);
}
}
void hou(SN *a)//后序遍历
{
if(a)
{
hou(a->left);
hou(a->right);
cout<<a->val<<' ';
}
}
完整代码:
//二叉树的创建和前、中、后的遍历
#include <iostream>
#include <bits/stdc++.h>
#include <malloc.h>
using namespace std;
typedef struct note
{
int val;
struct note *left;
struct note *right;
}SN;
void creat(SN* &a)//创建二叉树
{
int k;
cin>>k;
if(k!=0)
{
a=(SN *)malloc(sizeof(SN));
a->val=k;
creat(a->left);
creat(a->right);
}
else
a=NULL;
}
void xian(SN *a)//先序遍历
{
if(a!=NULL)
{
cout<<a->val<<' ';
xian(a->left);
xian(a->right);
}
}
void zhong(SN *a)//中序遍历
{
if(a)
{
zhong(a->left);
cout<<a->val<<' ';
zhong(a->right);
}
}
void hou(SN *a)//后序遍历
{
if(a)
{
hou(a->left);
hou(a->right);
cout<<a->val<<' ';
}
}
int main()
{
SN *root=NULL;
creat(root);
xian(root);
cout<<endl;
zhong(root);
cout<<endl;
hou(root);
cout<<endl;
return 0;
}
下面的是一些练习题
P1296 奶牛的耳语
题目描述
在你的养牛场,所有的奶牛都养在一排呈直线的牛栏中。一共有 n 头奶牛,其中第 i 头牛在直线上所处的位置可以用一个整数坐标 pi(0≤pi≤108) 来表示。在无聊的日子里,奶牛们常常在自己的牛栏里与其它奶牛交流一些八卦新闻。每头奶牛发出的声音响度是一样的,而由于声波的能量衰减,某头奶牛发出的声音只能被与它距离不超过d(0≤d≤104) 的奶牛所听到,这样这对奶牛就称为可以相互交流的。现在给出所有奶牛的位置和声音所能传播的最远距离 d ,请你编个程序来计算你的养牛场里究竟有多少对可以相互交流的奶牛。
输入格式
第一行包含两个整数 n,d。
第二行包含 n 个整数,每个整数都是一个坐标 pi,描述一头奶牛在直线上的位置。
输出格式
一个数,表示养牛场中可以相互交流奶牛的对数。
输入输出样例
输入 #1复制
5 10 10 12 16 37 40
输出 #1复制
4
说明/提示
数据规模
对于 40%40% 的数据,1≤n≤103。
对于 100%100% 的数据,1≤n≤106。
这是一道二分题,其实跟A-B数对差不多,先给它升序一下,然后二分查找到第一个差大于d的就结束,下标相减。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int a[1000010];
int main()
{
int n,d;
cin>>n>>d;
for(int i=0;i<n;i++)
cin>>a[i];
int sum=0;
sort(a,a+n);
int k=0;
for(int i=0;i<n-1;i++)
{
int l=0,r=n-1;
while(l<r)
{
int mid=(l+r)/2;
if(a[mid]-a[i]>d)
r=mid;
else
l=mid+1;
}
sum+=l-i;
if(a[l]-a[i]>d)//删去重复计算的
sum--;
}
cout << sum << endl;
return 0;
}
P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布
题目背景
NOIP2014 提高组 D1T1
题目描述
石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第 8 集中出现了一种石头剪刀布的升级版游戏。
升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:
斯波克:《星际迷航》主角之一。
蜥蜴人:《星际迷航》中的反面角色。
这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果。
现在,小 A 和小 B 尝试玩这种升级版的猜拳游戏。已知他们的出拳都是有周期性规律的,但周期长度不一定相等。例如:如果小 A 以 石头-布-石头-剪刀-蜥蜴人-斯波克
长度为 66 的周期出拳,那么他的出拳序列就是 石头-布-石头-剪刀-蜥蜴人-斯波克-石头-布-石头-剪刀-蜥蜴人-斯波克-...
,而如果小 B 以 剪刀-石头-布-斯波克-蜥蜴人
长度为 55 的周期出拳,那么他出拳的序列就是 剪刀-石头-布-斯波克-蜥蜴人-剪刀-石头-布-斯波克-蜥蜴人-...
。
已知小 A 和小 B 一共进行 N 次猜拳。每一次赢的人得 11 分,输的得 00 分;平局两人都得 00 分。现请你统计 N 次猜拳结束之后两人的得分。
输入格式
第一行包含三个整数N,NA,NB,分别表示共进行 N 次猜拳、小 A 出拳的周期长度,小 B 出拳的周期长度。数与数之间以一个空格分隔。
第二行包含 NA 个整数,表示小 A 出拳的规律,第三行包含 NB 个整数,表示小 B 出拳的规律。其中,00 表示 剪刀
,11 表示 石头
,22 表示 布
,33 表示 蜥蜴人
,44 表示 斯波克
。数与数之间以一个空格分隔。
输出格式
输出一行,包含两个整数,以一个空格分隔,分别表示小 A、小 B 的得分。
输入输出样例
输入 #1复制
10 5 6 0 1 2 3 4 0 3 4 2 1 0
输出 #1复制
6 2
输入 #2复制
9 5 5 0 1 2 3 4 1 0 3 2 4
输出 #2复制
4 4
说明/提示
对于 100%100% 的数据,0<N≤200,0<NA≤200,0<NB≤200 。
一道模拟题,把输赢的数据入录进去就行了,看看代码。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int A[210],B[210];
int main()
{
int n,a,b;
int Asum=0,Bsum=0;
cin>>n>>a>>b;
for(int i=0;i<a;i++)
cin>>A[i];
for(int i=0;i<b;i++)
cin>>B[i];
for(int i=0;i<n;i++)
{
switch(A[i%a])
{
case 0:switch(B[i%b])
{
case 0:break;
case 1:Bsum++;break;
case 2:Asum++;break;
case 3:Asum++;break;
case 4:Bsum++;break;
} break;
case 1:switch(B[i%b])
{
case 0:Asum++;break;
case 1:break;
case 2:Bsum++;break;
case 3:Asum++;break;
case 4:Bsum++;break;
} break;
case 2:switch(B[i%b])
{
case 0:Bsum++;break;
case 1:Asum++;break;
case 2:break;
case 3:Bsum++;break;
case 4:Asum++;break;
} break;
case 3:switch(B[i%b])
{
case 0:Bsum++;break;
case 1:Bsum++;break;
case 2:Asum++;break;
case 3:break;
case 4:Asum++;break;
} break;
case 4:switch(B[i%b])
{
case 0:Asum++;break;
case 1:Asum++;break;
case 2:Bsum++;break;
case 3:Bsum++;break;
case 4:break;
} break;
}
}
cout << Asum<<' '<<Bsum << endl;
return 0;
}