码迷,mamicode.com
首页 > 其他好文 > 详细

编程小练习 OJ题 06

时间:2015-03-29 19:37:21      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:c++   动态规划   二叉树   

一元多项式化简

对输入的一元多项式,进行同类项合并,并按指数降序排序,输出处理后的一元多项式。如输入: "7X^4-5X^6+3X^3",输出: "-5X^6+7X^4+3X^3".

#include <map>
#include <string>
#include <stdlib.h>
#include <iostream>
using namespace std;

void OrderPolynomial (char* InputString, char* OutputString)
{
    map< int, int, greater<int> > m;
    string input(InputString);

    if(input[0] != '-') {
        input = "+" + input + "+";
    } else {
        input = input + "+";
    }
    unsigned int len = input.length();

    bool isCoeff = true;
    bool isMinus = false;
    int coefficient = 0, exponent = 0;

    for(unsigned int i = 0; i < len; ++i) {
        if(input[i] == '-') {
            isCoeff = true;
            isMinus = true;
        }

        if(input[i] == '+') {
            isCoeff = true;
            isMinus = false;
        }

        if(input[i] >= '0' && input[i] <= '9') {
            if(isCoeff){
                coefficient = coefficient * 10 + input[i] - '0';
            } else {
                exponent = exponent * 10 + input[i] - '0';
            }
        }

        if(input[i] == 'X') {
            isCoeff = false;
            if(isMinus){
                coefficient = coefficient * -1;
            }
        }

        if( (input[i] == '+' || input[i] == '-') && i != 0 ) {
            if(m.count(exponent) == 0){
                m[exponent] = coefficient;
            } else {
                m[exponent] += coefficient;
            }
            coefficient = 0;
            exponent = 0;
        }
    }

    string output = "";
    map< int, int, greater<int> >::iterator it;
    for(it = m.begin(); it != m.end(); ++it) {
        char cc[20], ee[20];
        itoa(it->second, cc, 10);
        itoa(it->first, ee, 10);
        string c(cc);
        string e(ee);
         if( it->second > 0 && it == m.begin() ) {
            output += (c + "X^" + e);
        }
        if( it->second > 0 && it != m.begin() ) {
            output += ("+" + c + "X^" + e);
        }
        if(it->second < 0) {
            output += (c + "X^" + e);
        }
    }

    output.copy(OutputString, output.length(),0);
    return;
}

二叉树遍历(由前序中序求后序)

给出一个二叉树的前序和中序,求其后序。

#include <iostream>
#include <string>
using namespace std;

typedef struct Node{
    char c;
    struct Node *left;
    struct Node *right;
}Node, *PNode;

static string pre;
static string mid;

void creatTreeByPreMid(PNode &p, int i, int j, int len){
    if (len <= 0) return;
    p = new Node;
    p->c = pre[i];
    p->left = NULL;
    p->right = NULL;
    int m = mid.find_first_of(pre[i]);
    creatTreeByPreMid(p->left, i + 1, j, m - j);
    creatTreeByPreMid(p->right, i + 1 + (m - j), m + 1, len - 1 - (m - j));
}

void postTraverse(PNode p){
    if (p) {
        postTraverse(p->left);
        postTraverse(p->right);
        cout << p->c;
    }
}

int main(){
    while (cin >> pre >> mid) {
        PNode root;
        creatTreeByPreMid(root, 0, 0, pre.length());
        postTraverse(root);
        cout << endl;
    }
    return 0;
}

合唱队(最长递增子序列)

一排同学N个,出队K个后,其他同学身高满足T1 < T2 < … < Ti , Ti > Ti+1 > … > TK (1 <= i <= K),求至少需要出队多少。输入首行表示同学个数N,第二行依次为每个同学的身高。

#include <iostream>
using namespace std;

int main(){
    int n, sum = 0;
    cin >> n;
    int inc1[200], inc2[200], a[200];
    for (int i = 1; i <= n; ++i)
        cin >> a[i];

    inc1[1] = 1;
    // inc1[i] 从左到 a[i] 最长上升子序列
    // 状态转移递推式: inc1[i] = max{ inc1[j] | (1 <= j < i) 且 a[i] > a[j] } + 1
    for (int i = 2; i <= n; ++i) {
        inc1[i] = 1;
        for (int j = 1; j < i; ++j) {
            if (a[i] > a[j] && inc1[j] + 1 > inc1[i])
                inc1[i] = inc1[j] + 1;
        }
    }

    inc2[n] = 1;
    for (int i = n - 1; i >= 1; --i) {
        inc2[i] = 1;
        for (int j = n; j > i; --j) {
            if (a[i] > a[j] && inc2[j] + 1 > inc2[i])
                inc2[i] = inc2[j] + 1;
        }
    }

    for (int i = 1; i <= n; ++i) {
        if (inc1[i] + inc2[i] - 1 > sum)
            sum = inc1[i] + inc2[i] - 1;
    }
    cout << n - sum;
    return 0;
}

整数分隔(2的幂的和)

一个整数拆成2的幂的和,求可以拆分的种数,输入n,输出 f(n) % 1000000000。

#include <iostream>
using namespace std;

// 一个整数总可以拆分为 2 的幂的和, 给定一个整数,求有多少种拆分方法
int main() {
    int *p = new int[1000001];
    int n;
    while (cin >> n) {
        p[0] = p[1] = 1;
        for (int i = 2; i <= n; ++i) {
            if (i % 2)
                p[i] = p[i - 1];
            else
                p[i] = (p[i - 1] + p[i / 2]) % 1000000000;
        }
        cout << p[n] << endl;
    }
    delete[] p;
    return 0;
}

大数求和

输入输出用字符串表示大数

#include <iostream>
#include <string>
using namespace std;

void str2num(string str, int num[]){
    for (unsigned int i = 0; i < str.length(); ++i) {
        num[str.length() - 1 - i] = str[i] - '0';
    }
}

// 大数求和,数字以字符串形式输入不超过100位
int main(){
    string a, b;
    cin >> a >> b;
    int na[101] = { 0 };
    int nb[100] = { 0 };
    str2num(a, na);
    str2num(b, nb);
    for (unsigned int i = 0; i < 100; ++i) {
        na[i] += nb[i];
        na[i + 1] += na[i] / 10;
        na[i] %= 10;
    }
    int i = 100;
    for (; i >= 0; --i) {
        if (na[i] != 0) {
            break;
        }
    }
    for (; i >= 0; --i) {
        cout << na[i];
    }
    return 0;
}

名字的漂亮度

名字为小写字母,其漂亮度是其所有字母漂亮度的总和,每个字母的漂亮度范围在1到26之间,并且都不同,求最大漂亮度。

#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <vector>
#include <functional>
using namespace std;

// 名字是小写字母,与漂亮度数字[1,26]里的值一一对应自己安排,求名字的最大漂亮度值。
int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        string str;
        cin >> str;
        map<char, int> m;
        for (unsigned int i = 0; i < str.size(); ++i) {
            if (m.count(str[i]) == 0) {
                m[str[i]] = 1;
            } else {
                ++m[str[i]];
            }
        }
        map<char, int>::iterator it;
        vector<int> ve;
        for (it = m.begin(); it != m.end(); ++it) {
            ve.push_back(it->second);
        }
        sort(ve.begin(), ve.end(), greater<int>());
        int sum = 0;
        for (unsigned int i = 0, j = 26; i < ve.size(); ++i,--j) {
            sum += ve[i] * j;
        }
        cout << sum << endl;
    }
    return 0;
}

报数

有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出,问最后留下的那位是原来第几号。

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n;
    while (cin >> n) {
        vector<int> ve;
        for (int i = 1; i <= n; ++i) {
            ve.push_back(i);
        }

        int out = 0, count = 0, index = 0;
        while (out < n - 1) {
            if (ve[index] != 0) {
                ++count;
            }
            if (count == 3) {
                ve[index] = 0;
                count = 0;
                ++out;
            }
            ++index;
            if (index == n) {
                index = 0;
            }
        }

        for (unsigned int i = 0; i < ve.size(); ++i) {
            if (ve[i] != 0) {
                cout << ve[i] << endl;
                break;
            }
        }
    }
    return 0;
}

编程小练习 OJ题 06

标签:c++   动态规划   二叉树   

原文地址:http://blog.csdn.net/thisinnocence/article/details/44729237

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!