CSDN 编程竞赛二十二期题解

竞赛总览

CSDN 编程竞赛二十二期:比赛详情 (csdn.net)

竞赛题解

题目1、c++难题-大数加法

大数一直是一个c语言的一个难题。现在我们需要你手动模拟出大数加法过程。请你给出两个大整数加法结果。

如题,大数一直是一个c语言的一个难题。本人对C++的大数运算确实不太了解,所以无法直接使用系统的大数类;而自己实现大数运算类也要手敲一堆代码,这种方式显然不太划算。

实现大数加法的思路其实很简单,首先将操作数1和操作数2从右向左取出来每一位,存入数组中。

例如,1234+567,先存入数组:

A [4, 3, 2, 1]

B [5, 6, 7]

然后顺着从左往右加就行(A [i] + B [i] + 前一位的进位C),短的数组后面缺失的位当0处理即可。

完成之后,再从右往左取出来,即可得到大数加法的运算结果。

不过,大数一直是一个c语言的一个难题,如果不使用c语言,问题就迎刃而解了。

可以使用Java自带的大数类来完成大数加法,简单粗暴。

也可以使用Python,Python支持直接大数运算,代码可以更简短。

题目2、最长回文串

找出最先出现的最长回文串(“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串)。

#include 
#include 
#include 

int match (std::string& str, int& x_ret, int& y_ret) {
    int result = 1;
    for (int i = 0; i < str.length (); i++) {
        for (int j = 0; j < 2; j++) {
            int x = i - j;
            int y = i + 1;
            while (x > -1 && y < str.length () && str [x] == str [y]) {
                x--;
                y++;
            }
            int len = y - x - 1;
            if (result < len) {
                result = len;
                x_ret = x;
                y_ret = y;
            }
        }
    }
    return result;
}

int main () {
    std::string str;
    std::cin >> str;
    int x = 0, y = 0;
    int result = match (str, x, y);
    printf ("%d", result);
    return 0;
}

直接打回文串模板即可。本题要求输出回文串的内容,而不是长度,因此代码稍加改进即可通过。

题目3、求最小元素

假设按照升序排序的数组在预先未知的某个点上进行了旋转,请找到数组中最小元素(例如数据[0,1,2,4,5,6,7]可能变为[4,5,6,7,0,1,2],最小元素是0)。您可以假设阵列中不存在重复项。

#include 

int main () {
    int result;
    int n, result;
    scanf ("%d %d", &n, &result);
    for (int i = 1; i < n; i++) {
        int t; scanf ("%d", &t);
        result = min (t, result);
    }
    return 0;
}

假设第一个数就是最小的数,先将其记录到result中。之后继续读入新数据,如果比result更小,更新result即可。

题目4、最大数

给定任意一个数字m,然后给出数字n,则需在m中去掉n位数,保持各位顺序不变的情况下,得到最大数。

#include 
#include 
#include 

struct node {
    int num;
    int index;
};

int main () {
    std::string n; std::cin >> n;
    int m; scanf ("%d", &m);
    int len = n.length ();
    if (len <= m) {
        printf ("0");
        return 0;
    }

    node data [len];
    for (int i = 0; i < len; i++) {
        data [data [i].index = i].num = n [i] - '0';
    }

    for (int i = 0; i < len; i++) {
        for (int j = i + 1; j < len; j++) {
            if (data [i].num > data [j].num) {
                node tmp = data [i];
                data [i] = data [j];
                data [j] = tmp;
            }
        }
    }

    for (int i = 0; i < m; i++) data [i].num = -1;

    for (int i = 0; i < len; i++) {
        for (int j = i + 1; j < len; j++) {
            if (data [i].index > data [j].index) {
                node tmp = data [i];
                data [i] = data [j];
                data [j] = tmp;
            }
        }
    }

    for (int i = 0; i < len; i++) {
        if (data [i].num == -1) continue;
        printf ("%d", data [i].num);
    }
    return 0;
}

这道题直接暴力求解的,不过只能通过50%的测试数据。

首先将数字n当字符串输入进来,然后将每一位分别取出来存入到数组中。

根据每一位的值进行排序,去掉前m个最小值(记录为-1,表示删掉该位)。

然后再根据每一位的位置重新进行排序,恢复原有顺序。

之后输出每一位的值,如果遇到-1说明该位被删除,跳过即可。

没找到这道题的坑,不知道另外50%的测试数据是什么情况

这道题的坑如下:当需要删除较靠后的数字时,剩下的数字有可能不够len(n)-m位,从而将原本的首位挤到靠后的位置,导致得到的结果不是最大数。

// 1635427 3 6547
// 1563428 3 6428

以上思路仅供参考。

你可能感兴趣的:(CSDN,竞赛题解,算法,c++)