刷题笔记day6
【PAT A1086】 Tree Traversals Again
#include<stdio.h> #include<string.h> #include<stdlib.h> struct node { struct node* lchild; struct node* rchild; int data; }; int pre[50]; int precount = 0; int in[50]; int incount = 0; int s[100]; int top = 0; struct node* create(int prel,int prer,int inl,int inr) { if(prel > prer) return NULL; struct node* tree = (struct node*)malloc(sizeof(struct node)); int root = pre[prel]; tree->data = root; int k; for(k=inl;k<=inr;k++) { if(in[k] == root) break; } int numleft = k-inl; tree->lchild = create(prel+1,prel+numleft,inl,k-1); tree->rchild = create(prel+numleft+1,prer,k+1,inr); return tree; } int kong = 0; void post(struct node* tree) { if(tree == NULL) return; post(tree->lchild); post(tree->rchild); if(kong == 0) { kong++; } else printf(" "); printf("%d",tree->data); } int main() { int n; scanf("%d",&n); char str[10]; int time = 2*n; while(time--) { scanf("%s",str); if(strcmp(str,"Push")==0) { int x; scanf("%d",&x); pre[precount++] = x; s[top++] = x; } else if(strcmp(str,"Pop")==0) { in[incount++] = s[top-1]; top--; } } struct node* ans = create(0,n-1,0,n-1); post(ans); }
6-5 链式表操作集
#include <stdio.h> #include <stdlib.h> #define ERROR NULL typedef int ElementType; typedef struct LNode *PtrToLNode; struct LNode { ElementType Data; PtrToLNode Next; }; typedef PtrToLNode Position; typedef PtrToLNode List; Position Find( List L, ElementType X ); List Insert( List L, ElementType X, Position P ); List Delete( List L, Position P ); int main() { List L; ElementType X; Position P, tmp; int N; L = NULL; scanf("%d", &N); while ( N-- ) { scanf("%d", &X); L = Insert(L, X, L); if ( L==ERROR ) printf("Wrong Answer\n"); } scanf("%d", &N); while ( N-- ) { scanf("%d", &X); P = Find(L, X); if ( P == ERROR ) printf("Finding Error: %d is not in.\n", X); else { L = Delete(L, P); printf("%d is found and deleted.\n", X); if ( L==ERROR ) printf("Wrong Answer or Empty List.\n"); } } L = Insert(L, X, NULL); if ( L==ERROR ) printf("Wrong Answer\n"); else printf("%d is inserted as the last element.\n", X); P = (Position)malloc(sizeof(struct LNode)); tmp = Insert(L, X, P); if ( tmp!=ERROR ) printf("Wrong Answer\n"); tmp = Delete(L, P); if ( tmp!=ERROR ) printf("Wrong Answer\n"); for ( P=L; P; P = P->Next ) printf("%d ", P->Data); return 0; } Position Find( List L, ElementType X ) { List p = L; while(p!=NULL) { if(p->Data == X) return p; p = p->Next; } return ERROR; } List Insert( List L, ElementType X, Position P ) { if(L == P) { List x = (List)malloc(sizeof(struct LNode)); x->Data = X; x->Next = L; return x; } List pre = L; while(pre->Next != NULL && pre->Next != P) { pre = pre->Next; } if(pre->Next != P) { printf("Wrong Position for Insertion\n"); return ERROR; } List cha = (List)malloc(sizeof(struct LNode)); cha->Data = X; cha->Next = P; pre->Next = cha; return L; } List Delete( List L, Position P ) { if(L == NULL) { printf("Wrong Position for Deletion\n"); return ERROR; } if(L == P) { return P->Next; } List pre = L; while(pre->Next != NULL && pre->Next != P) { pre = pre->Next; } if(pre->Next != P) { printf("Wrong Position for Deletion\n"); return ERROR; } pre->Next = P->Next; return L; }
【codeup】 BFS 求矩阵中的块数
一种简单的bfs应用,有点类似涂色问题。
#include<cstdio> #include<queue> using namespace std; int n,m; int matrix[30][30]; int inq[30][30]; int xx[] = {0,0,1,-1}; int yy[] = {1,-1,0,0}; struct Node { int x; int y; }node; int judge(int x,int y) { if(x<0||x>=n||y<0||y>=m) return false; if(matrix[x][y]==0 || inq[x][y]== 1) return false; return true; } void bfs(int x,int y) { queue<Node> q; node.x = x; node.y = y; q.push(node); inq[x][y] = 1; while(!q.empty()) { Node top = q.front(); q.pop(); for(int i=0;i<4;i++) { int tempx = top.x + xx[i]; int tempy = top.y + yy[i]; if(judge(tempx,tempy) ) { node.x = tempx; node.y = tempy; q.push(node); inq[tempx][tempy] = 1; } } } } int main() { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { scanf("%d",&matrix[i][j]); inq[i][j] = 0; } } int ans = 0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(matrix[i][j] == 1 && inq[i][j] == 0) { ans++; bfs(i,j); } } } printf("%d\n",ans); }
【PAT A1004】 Counting Leaves
不要漏了这句话: For the sake of simplicity, let us fix the root ID to be 01
.
这题用纯c写太麻烦了,因为要自己重新实现一遍循环队列。。。所以使用了stl。
#include<cstdio> #include<vector> #include<queue> using namespace std; int leaf[105]={0};//ans int h[105];//存放层号 vector<int> g[105];//树 int max_h = 0;//最大深度 void bfs() { queue<int> q; q.push(1); while(!q.empty()) { int id = q.front(); q.pop(); //更新最大深度 max_h = max(max_h,h[id]); if(g[id].size() == 0) leaf[h[id]]++; //更新剩余节点深度 for(int i=0;i<g[id].size();i++) { h[g[id][i]] = h[id]+1; q.push(g[id][i]); } } } int main() { int n; int m; scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int id; int k; scanf("%d%d",&id,&k); for(int j=0;j<k;j++) { int temp; scanf("%d",&temp); g[id].push_back(temp); } } h[1] = 1; bfs(); for(int i=1;i<=max_h;i++) { if(i!=1)printf(" "); printf("%d",leaf[i]); } return 0; }
【PAT A1085】Perfect Sequence
注意qsort的cmp函数必须用指针交换。
#include<stdio.h> #include<stdlib.h> #include<math.h> //#include<algorithm> //using namespace std; int ma(int a,int b) { if(a>b)return a; else return b; } int cmp(const void* a,const void* b) { long long* c = (long long* )a; long long* d = (long long* )b; return *c-*d; } int main() { long long n,p; scanf("%lld%lld",&n,&p); long long a[100005]; int k; for(k=0;k<n;k++) scanf("%lld",&a[k]); //sort(a,a+n); qsort(a,n,sizeof(a[0]),cmp); //for(k=0;k<n;k++) //printf("%d ",a[k]); int i=0; int j=0; int ccount=1; while(i<n && j<n) { while(j<n && a[j]<=(long long )a[i]*p) { if(j-i+1>ccount) ccount = j-i+1; j++; } i++; //printf("%d\n",ccount); } printf("%d\n",ccount); }
6-8 求二叉树高度
int GetHeight( BinTree BT ) { if(BT == NULL) return 0; else { int left = GetHeight(BT->Left); int right = GetHeight(BT->Right); if(left < right) return right + 1; else return left +1; } }
7-3 树的同构
这题真的做到头秃。
遇到的坑总结如下:
1. 用纯c实现,输入%c时,要注意吸收输入完数字之后的空格。
2. 判同构的算法,直接判断左左右右、左右左右子树也是可以的。
3. 如果n1或者n2位零,也就是空树的情况,需要特别讨论。
#include<stdio.h> #include<stdlib.h> struct Node { char x; int lchild; int rchild; }t1[20],t2[20]; int check1[20]={0}; int check2[20]={0}; int issame(int root1,int root2) { if(root1 == -1 && root2 == -1) return 1; if(root1 != -1 && root2 == -1) return 0; if(root1 == -1 && root2 != -1) return 0; if(t1[root1].x!=t2[root2].x) return 0; if(t1[root1].lchild == NULL && t2[root2].lchild == NULL) { return issame(t1[root1].rchild,t2[root2].rchild); } if(t1[t1[root1].lchild].x == t2[t2[root2].lchild].x) return issame(t1[root1].rchild,t2[root2].rchild) && issame(t1[root1].lchild,t2[root2].lchild); else return issame(t1[root1].lchild,t2[root2].rchild) && issame(t1[root1].rchild,t2[root2].lchild); return 0; } int main() { int n1,n2; scanf("%d",&n1); int i; for(i=0;i<n1;i++) { char l,r; scanf("%*c%c%*c%c%*c%c",&t1[i].x,&l,&r); //printf("%c%c%c\n",t1[i].x,l,r); if(l=='-') t1[i].lchild = -1; else { t1[i].lchild = l-'0'; check1[t1[i].lchild] = 1; } if(r=='-') t1[i].rchild = -1; else { t1[i].rchild = r-'0'; check1[t1[i].rchild] = 1; } } scanf("%d",&n2); if(n1 == n2 && n1 == 0) { printf("Yes\n"); return 0; } else if(n1 == 0 || n2 == 0) { printf("No\n"); return 0; } for(i=0;i<n2;i++) { char l,r; scanf("%*c%c%*c%c%*c%c",&t2[i].x,&l,&r); //printf("%c%c%c\n",t2[i].x,l,r); if(l=='-') t2[i].lchild = -1; else { t2[i].lchild = l-'0'; check2[t2[i].lchild] = 1; } if(r=='-') t2[i].rchild = -1; else { t2[i].rchild = r-'0'; check2[t2[i].rchild] = 1; } } int root1,root2; for(i=0;i<n1;i++) { if(check1[i] == 0) { root1 = i; break; } } for(i=0;i<n2;i++) { if(check2[i] == 0) { root2 = i; break; } } //printf("root1:%d\n",root1); //printf("root2:%d\n",root2); int ans = issame(root1,root2); if(ans == 0) printf("No\n"); else printf("Yes\n"); }
直接判断左左右右、左右左右子树
int issame(int root1,int root2) { if(root1 == -1 && root2 == -1) return 1; if(root1 != -1 && root2 == -1) return 0; if(root1 == -1 && root2 != -1) return 0; if(t1[root1].x!=t2[root2].x) return 0; if(issame(t1[root1].lchild,t2[root2].lchild) && issame(t1[root1].rchild,t2[root2].rchild)) return 1; if(issame(t1[root1].rchild,t2[root2].lchild) && issame(t1[root1].lchild,t2[root2].rchild)) return 1; return 0; }