CSP历年复赛题-P1087 [NOIP2004 普及组] FBI 树

原题链接:https://www.luogu.com.cn/problem/P1087

题意解读:字符串作为根,左边一半作为左子树,右边一半作为右子树,递归构造数,并按FBI规则输出后续遍历结果。

解题思路:

按照题意,通过dfs来构造树,对于字符串str,提取左边一半递归构造左子树,提取右边一半递归构造右子树,前提是字符串长度>1

输出根的位置在左、右子树dfs之后,即为后续遍历。

根据字符串的提取方法,有两种程序实现,一种是对string进行处理,一种是直接通过下标来变换,下面给出两种代码:

string str1 = "123456";

string str2(str1, 0, 3); //str2 = "123",表示从第0个开始3个字符

string str3(str1, 3); //str3 = "456",表示从第3个开始直到最后所有字符

100分代码-string处理:

#include <bits/stdc++.h>
using namespace std;

void print(string str)
{
    int sum = 0;
    for(int i = 0; i < str.size(); i++) sum += str[i] - '0';
    if(sum == 0) cout << "B";
    else if(sum == str.size()) cout << "I";
    else cout << "F";
}

void dfs(string str)
{
    if(str.size() > 1)
    {
        string left(str, 0, str.size() / 2);
        string right(str, str.size() / 2);
        dfs(left);
        dfs(right);
    }
    print(str);
}

int main()
{
    int n;
    string s;
    cin >> n >> s;
    dfs(s);
    return 0;
}

100分代码-下标变换:

#include <bits/stdc++.h>
using namespace std;

int n;
string s;

void print(int l, int r)
{
    int sum = 0;
    for(int i = l; i <= r; i++) sum += s[i] - '0';
    if(sum == 0) cout << "B";
    else if(sum == r - l + 1) cout << "I";
    else cout << "F";
}

void dfs(int l, int r)
{
    if(r - l + 1 > 1)
    {
        dfs(l, l + (r - l + 1) / 2 - 1);
        dfs(l + (r - l + 1) / 2, r);
    }
    print(l, r);
}

int main()
{
    cin >> n >> s;
    dfs(0, s.size() - 1);
    return 0;
}

 

posted @ 2024-05-23 11:06  五月江城  阅读(41)  评论(0编辑  收藏  举报