分治 堆


//一直前序和中序求后序
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 1e6 + 100; int pr[maxn], in[maxn], n; /*pr储存前序遍历,in储存中序遍历*/ int Left[maxn], Right[maxn], root; //二叉树相关 bool ok; //根据前序和中序建树 int build(int L1, int R1, int L2, int R2) { if(L1 > R1) return 0; int rt = pr[L1]; int p = 1; while(in[p] != rt) ++p; //在中序中找到根结点 Left[rt] = build(L1+1, L1 + p-L2, L2, p-1); //递归建立左子树 Right[rt] = build(L1+ p-L2 + 1, R1, p+1, R2); //递归建立右子树 return rt; //返回根结点 } //后序遍历 void poOrder(int rt) { if(Left[rt] != 0) poOrder(Left[rt]); if(Right[rt] != 0) poOrder(Right[rt]); if(ok) cout << " "; if(!ok) ok = 1; cout << rt; } int main() { while(scanf("%d", &n) == 1) { //初始化+输入 memset(Left, 0, sizeof(Left)); memset(Right, 0, sizeof(Right)); for(int i = 1; i <= n; ++i) scanf("%d", &pr[i]); for(int i = 1; i <= n; ++i) scanf("%d", &in[i]); root = build(1,n,1,n); //建树 ok = 0; poOrder(root); //后序遍历输出结果 cout << endl; } return 0; }
//根据树的后序和中序,求层次遍历。
#include<bits/stdc++.h> using namespace std; const int maxn = 30; int a[maxn + 10], b[maxn + 10]; map<int, int>L, R; //L[i]表示i的左子节点,R[i]表示i的右子节点 //当前考虑的是后序遍历[la, ra]区间和对应的中序遍历[lb,rb]区间 int build(int la, int ra, int lb, int rb) { if (la > ra) //越界判断 { return 0; } int root = a[ra]; //后序遍历右一肯定是根 int i; for (i = lb; i <= rb && b[i] != root; i++) {} //在中序遍历中找到这个节点下标i if (i <= rb) //递归分治 { R[root] = build(ra - rb + i, ra - 1, i + 1, rb); L[root] = build(la, ra - rb + i - 1, lb, i - 1); } return root; } void bfs(int root) { queue<int> Q; Q.push(root); int cnt = 0; while (!Q.empty()) { int tn = Q.front(); Q.pop(); printf(cnt++ == 0 ? "%d" : " %d", tn); if (L[tn]) { Q.push(L[tn]); } if (R[tn]) { Q.push(R[tn]); } } puts(""); } int main() { int N; scanf("%d", &N); for (int i = 1; i <= N; i++) { scanf("%d", &a[i]); } for (int i = 1; i <= N; i++) { scanf("%d", &b[i]); } int root = build(1, N, 1, N); bfs(root); return 0; }
//根据树的中序和按层遍历,求先序遍历。
#include<iostream> #include<cstring> using namespace std; string s1,s2; void calc(int l1,int r1,int l2,int r2) { int i,j; for(i=l2;i<=r2;i++)//找层次遍历中优先输出根节点的位置 ,根肯定在儿子的前面。 { int b=0; for(j=l1;j<=r1;j++) { if(s2[i]==s1[j]) { cout<<s1[j];//输出根节点 b=1; break; } } if(b) break; } if(j>l1) calc(l1,j-1,0,r2);//遍历左子树 if(j<r1) calc(j+1,r1,0,r2);//遍历右子树 } int main() { cin>>s1>>s2; calc(0,s1.length()-1,0,s2.length()-1); cout<<endl; return 0; }
//根据中序遍历和层次遍历,求后序遍历
#include<stdio.h> #include<string.h> int len,mark[102]; //用来给中序遍历做标记 char s1[102],s2[102]; //储存遍历 void tree(int l,int r){ //递归函数 if(l>r)return; //返回条件,不能等于 int i,j,min=0x7fffff/*int范围的最大值*/,root; for(i=l;i<=r;i++){ if(mark[s1[i]]<min){ min=mark[s1[i]];root=i; //在中序遍历中找到层次遍历里的最靠前的结点(即先序遍历中要求优先输出的根结点 } } printf("%c",s1[root]); //输出根结点 tree(l,root-1); //先遍历左子树 tree(root+1,r); //再遍历右子树,顺序不能调换 } int main(){ scanf("%s%s",s1+1,s2+1); len=strlen(s2+1); int i; for(i=1;i<=len;i++) mark[s2[i]]=i; //做标记,虽然s2[i]为字符,但视为ASCII码值,越靠前标记值越小 tree(1,len); }

https://www.cnblogs.com/jhz033/p/5571233.html 刷围墙,一道分治的题目,可以用dp;

 

https://www.cnblogs.com/helloworld-c/p/4854463.html 堆

https://blog.csdn.net/Dream_Weave/article/details/82526775

https://blog.csdn.net/qq_38779698/article/details/79759662 这个比较简单。

https://pintia.cn/problem-sets/1104020079991836672/problems/1104020194857046027 题目链接

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;

struct heap {
int sum, num[1005];
int top() {
return num[1];
}
bool empty() {
if(sum == 0) return true;
return false;
}
void push(int a) {
num[++sum] = a;
int now = sum, temp;
while(now > 1 && num[now] > num[now / 2]) {
    temp = num[now];
    num[now] = num[now / 2];
    num[now / 2] = temp;
    now = now / 2;
}
}
void pop() {
int now = 1, temp;
num[now] = num[sum--];
while((now * 2 <= sum && num[now] < num[now * 2]) || (now * 2 + 1 <= sum && num[now] < num[now * 2 + 1])) {

    if(num[now * 2] > num[now * 2 + 1]) {
        temp = num[now];
        num[now] = num[now * 2];
        num[now * 2] = temp;
        now = now * 2;
    }
    else {
        temp = num[now];
        num[now] = num[now * 2 + 1];
        num[now * 2 + 1] = temp;
        now = now * 2 + 1;
    }
}
}
}a;

int main() {
int n;
cin >> n;
int b;
for(int i = 1; i <= n; i++) {
    cin >> b;
    a.push(b);
}
while(!a.empty()) {
    cout << a.top() << " ";
    a.pop();
}
return 0;
}

 

posted @ 2019-03-10 14:11  downrainsun  阅读(214)  评论(0编辑  收藏  举报