思想
一开始用邻接表加递归,总是超限,后来想想,有了父子关系,那么输入就是最好的判断。
心得
判断类的题目和求结果不一样,判断类的题目往往不用费常复杂的无脑运算,而是通过一些过程的比较和标记对flag进行改变,最终的出判断结果。
就比如我们的进程管理,也是判断类,通过设置mark数组,很好的实现了功能,而文件系统的话,毕竟要求出结果的,那就比较无脑了。
/*
输入样例
4
1
10
3
10 5 3
1 2
1 3
5
1 2 3 4 5
1 3
1 2
2 4
2 5
5
8 7 6 5 9
1 2
1 3
2 4
2 5
输出样例
Yes
No
Yes
*/
#include <bits/stdc++.h>
using namespace std;
int arr[105];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
memset(arr,0,sizeof(arr));
for(int i=1;i<=n;i++)
{
scanf("%d",&arr[i]);
}
int flag=1;
for(int i=0;i<n-1;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(arr[a]>arr[b])
{
flag=0;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}
寻找宝藏
- 寻找宝藏
时间限制 1000 ms 内存限制 65536 KB Special Judge
题目描述
有一棵多叉树T,你在树根处,宝藏在某一叶子节点L。现在你沿着树枝向叶子方向走去,从不回头,如果遇到树叉节点,你等概率地挑选一个分支继续走。请问,在给定T,L的情况下,你有多大概率拿到宝藏?
输入格式
第一行,整数
N M L
(1< N< 1000,0< M< 1000,0< L< N),分别代表树T上的节点数、树枝的个数,宝藏所在节点。树根为0号结点。然后有M行,每行两个整数A,B(0≤ A,B< N)代表从节点A到节点B有一条树枝。可以假设节点A
总是更靠近树根。
输出格式
所求的概率,输出四舍五入到6位小数,然后换行。
输入样例
6 5 5
0 1
1 3
0 2
2 4
2 5
输出样例
0.250000
思路
也是利用父子关系,是父亲到这个目标节点,每层所有的分支相乘做分母
代码
#include <bits/stdc++.h>
using namespace std;
vector<int>graph[1005];
int father[1005];
int main()
{
int n,m,l;
while(scanf("%d%d%d",&n,&m,&l)!=EOF)
{
memset(graph,0,sizeof(graph));
memset(father,0,sizeof(father));
father[0]=-1;
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
father[b]=a;
graph[a].push_back(b);
}
double fenmu=1;
while(father[l]!=-1)
{
l=father[l];
fenmu*=graph[l].size();
}
double answer=1.0/double(fenmu);
printf("%.6f\n",answer);
}
return 0;
}
总结
这类技巧性的题型出现概率是很高的,一定要想好思路
先序遍历
心得:给定了父子关系,可以直接利用数组来模拟指针进行树的遍历操作,每次判断root是否为-1.
问题描述
代码
#include <bits/stdc++.h>
using namespace std;
/*
2
3
2
2 0 0
2 1 1
7
0
0 1 0
0 2 1
1 3 0
1 4 1
2 5 0
2 6 1
样例输出:
2 0 1
0 1 3 4 2 5 6
*/
struct tree{
int left;
int right;
};
tree son[50];
void Preorder(int root)
{
if(root==-1)
{
return ;
}
cout<<root<<" ";
Preorder(son[root].left);
Preorder(son[root].right);
return ;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int n; cin>>n;
for(int i=0;i<n;i++)
{
son[i].left=-1;
son[i].right=-1;
}
int root; cin>>root;
for(int i=0;i<n-1;i++)
{
int a,b,c;
cin>>a>>b>>c;
if(c==0) son[a].left=b;
if(c==1) son[a].right=b;
}
Preorder(root);
cout<<endl;
}
return 0;
}