感悟:
- 前两题我在40分钟内解决了,但实际上如果仔细一些可以在半小时内完成。
- 第三题是判断哈密顿环的问题,有一定的知识背景要求,当然学过图论的应该都知道一些的。
一开始我还觉得按照PAT的尿性,可能给的无向图的信息都是有迷惑性的,比如可能会有一些孤立点?但是实际上是没有的。
只要了解到环的特性:环长为点数+1,以及头尾是一样的。以及哈密顿的特性:所有点都经过。那么只剩下一个样例过不了了。
对于最后一个样例,我们还需要判断题目给出的这个path上那些相邻点是不是连通的,需要根据前面给出的图来进行判断,如果中间有一条边是断开的,那么就NO。
ac代码:
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
int M,N;
int G[210][210];
int book[210]={0};
int main(){
scanf("%d %d",&M,&N);
for(int i=0,m,n;i<N;i++){
scanf("%d %d",&m,&n);
G[m][n] = G[n][m] = 1;
}
int K,k,st,ed;
vector<int> path;
scanf("%d",&K);
for(int i=0;i<K;i++){
path.clear();
map<int,bool> mp;
scanf("%d",&k);
for(int j=0,m;j<k;j++){
scanf("%d",&m);
path.push_back(m);
mp[m] = 1;
if(j==0)
st = m;
if(j==k-1)
ed = m;
}
int j;
for(j=1;j<path.size();j++){
if(G[path[j-1]][path[j]]!=1){
printf("NO\n");
break;
}
}
if(j!=path.size()){
continue;
}
if(st!=ed){
printf("NO\n");
continue;
}
for(j=1;j<=M;j++)
if(mp[j]==0){
printf("NO\n");
break;
}
if(j!=M+1)
continue;
if(k!=M+1){
printf("NO\n");
continue;
}
printf("YES\n");
}
}
- 最后一题关于AVL的可以说是完全忘记了,还需要多多复习。这里着重讲讲最后这题的思路。
A1123 Is It a Complete AVL Tree ?
首先我们需要AVL建树,建完后再层序遍历。层序遍历不难,但是AVL树怎么建是挺麻烦的。这里有两个注意点:
第一,需要考虑什么时候用引用
将指针看成是一棵树的根结点,如果这颗树的结构(注意是结构而不是值),那么就需要用引用!
第二,考虑什么时候updateHeight,即更新结点高度
这里我总结的就是,当一个结点移动过后,那么从下而上的进行更新 即可 !
**注意:insert(root->lchild,data)之后应该updateH(root)而不是root->lchild ! **
因为如果root->lchild本来是NULL,那新节点是完全没有必要更新的,递归次序反而导致最后的root不会被更新。
然后需要判断这是否为一颗完全树,事实上这道题就是两道题的融合hhhh
如何判断树是否完全?
我们可以参考堆,根下标为ind,左节点为2ind,右节点为2ind+1,。用递归的思想,记录下最大的下标数,如果和总结点数一样多,那么就是完全的了。
着重要注意这里的递归出口为当前结点为叶子时退出 !
if(root->lchild==NULL&&root->rchild==NULL){
记录最大下标
}
ac代码:
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
int data;
int height;
node* lchild;
node* rchild;
};
int getHeight(node* root){
if(root==NULL)return 0;
return root->height;
}
void updateHeight(node* root){
root->height = max(getHeight(root->lchild),getHeight(root->rchild))+1;
}
int getBF(node* root){
return getHeight(root->lchild)-getHeight(root->rchild);
}
void L(node* &root){
node* temp = root->rchild;
root->rchild = temp->lchild;
temp->lchild = root;
updateHeight(root);
updateHeight(temp);
root = temp;
}
void R(node* &root){
node* temp = root->lchild;
root->lchild = temp->rchild;
temp->rchild = root;
updateHeight(root);
updateHeight(temp);
root = temp;
}
void insert(node* &root,int data){
if(root==NULL){
root = new node;
root->data = data;
root->height = 1;
root->lchild = root->rchild = NULL;
}else{
if(data<root->data){
insert(root->lchild,data);
updateHeight(root);
if(getBF(root)==2){
int f = getBF(root->lchild);
if(f==1){//LL
R(root);
}else if(f==-1){//LR
L(root->lchild);
R(root);
}
}
}else{
insert(root->rchild,data);
updateHeight(root);
if(getBF(root)==-2){
int f = getBF(root->rchild);
if(f==-1){//RR
L(root);
}else if(f==1){//RL
R(root->rchild);
L(root);
}
}
}
}
}
node* Create(int a[],int n){
node* root = NULL;
for(int i=0;i<n;i++){
insert(root,a[i]);
}
return root;
}
void levelOrder(node* root){
queue<node*> q;
vector<int> v;
q.push(root);
while(!q.empty()){
node* temp = q.front();
v.push_back(temp->data);
if(temp->lchild!=NULL)q.push(temp->lchild);
if(temp->rchild!=NULL)q.push(temp->rchild);
q.pop();
}
for(int i=0;i<v.size();i++){
if(i!=0)
printf(" ");
printf("%d",v[i]);
}
}
int MAX = -1;
void func(node* root,int ind){
if(root->lchild==NULL&&root->rchild==NULL){
if(MAX<ind)
MAX = ind;
}else{
if(root->lchild!=NULL)func(root->lchild,2*ind);
if(root->rchild!=NULL)func(root->rchild,2*ind+1);
}
}
int main(){
int n;
int a[100];
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
node* root = Create(a,n);
levelOrder(root);
func(root,1);
if(MAX!=n)
printf("\nNO\n");
else
printf("\nYES\n");
}