2016码农谷全国大学生程序设计邀请赛(测试赛)

ACM模版

这是一个新兴的OJ,希望可以越办越好,以后也多一个训练自己的平台~~~

试题一 将字符串中的字符按规则重新排列

描述

请编写程序,将输入字符串中的字符按以下规则重新排列(字符串长度不超过 1000,同时满足所有规则)。 规则 1:英文字母从 A 到 Z 排列,不区分大小写。例如,输入“Much”则输出“chMu”。
规则 2:同一个英文字母的大小写同时存在时,按照输入顺序排列。例如,输入“BabA”则输出“aABb”。 规则 3:非英文字母的其它字符保持原来的位置。例如,输入“By?e”则输出“Be?y”。

输入描述
输入数据为一行字符串。

输出描述
输出数据为一行字符串。

样例:
输入:2016 MaNongGu.com Programming Contest
输出:2016 aacCegGg.giM mmmNnnnoooo Prrsttu

题解

先将非字母的存到另一个数组中,其他的原封不动,然后逐个查找字母填空。

代码

#include <iostream>

using namespace std;

string strA;
string strB;

int main(int argc, const char * argv[])
{
    int key = 0;
    char taga = 'a';
    char tagA = 'A';
    int count = 0;

    getline(cin, strA);

    for (int i = 0; i < strA.length(); i++)
    {
        if ((strA[i] >= 'a' && strA[i] <= 'z') || (strA[i] >= 'A' && strA[i] <= 'Z'))
        {
            strB[key++] = strA[i];
        }
    }

    for (int i = 0; i < strA.length(); i++)
    {
        if ((strA[i] >= 'a' && strA[i] <= 'z') || (strA[i] >= 'A' && strA[i] <= 'Z'))
        {
            bool flag = true;
        l:
            while (flag)
            {
                for (int j = 0; j < key; j++)
                {
                    if (strB[j] == taga + count || strB[j] == tagA + count)
                    {
                        strA[i] = strB[j];
                        strB[j] = '*';
                        flag = false;
                        goto l;
                    }
                }
                count++;
            }
        }
    }

    cout << strA << '\n';

    return 0;
}

试题二 统计出以某个字符串为前缀的单词数量

描述

老码农交给小码农很多单词(全部由小写字母组成,每个单词的长度不超过 10,且没有重复的单词),并要 他统计出以某个字符串为前缀的单词数量。注意:单词本身也是自己的前缀,例如,以字符串“is”为前缀 的单词有 is、iso、isoapiole 等。

输入描述: 第一部分是一张单词表,每行一个单词,字符串“88888888”代表单词表的结束(注意:单词表本身不包 括“88888888”)。第二部分是一连串的前缀字符串,每行一个。

输出描述: 对于每个前缀字符串,给出以该字符串为前缀的单词的数量,每行一个。

样例:
输入: manonggu
malonggu
model
absolute
acm
88888888
ma
m
ab
a
输出:
2
3
1
2

题解

一道常规的字符串匹配问题,甚至比常规的还简单。

代码

#include <iostream>
#include <string>

using namespace std;

string str[10000];
string flag;

int main(int argc, const char * argv[])
{
    int i = 0;
    while (cin >> str[i])
    {
        if (str[i] == "88888888")
        {
            break;
        }
        i++;
    }
    while (cin >> flag)
    {
        int ans = 0;
        for (int j = 0; j < i; j++)
        {
            bool tag = true;
            for (int k = 0; k < flag.length(); k++)
            {
                if (flag[k] != str[j][k])
                {
                    tag = false;
                    break;
                }
            }
            if (tag)
            {
                ans++;
            }
            tag = true;
        }
        cout << ans << '\n';
    }
    return 0;
}

试题三 将数分成两组,使得两组中各元素的和相等

描述

请编写程序,读取 N 个整数,如果这 N 个数同时满足以下所有条件则输出 1,否则输出 0: (1)能分成两组,使得两组中各元素的和相等。
(2)所有 5 的倍数必须在其中一个组中,所有 3 的倍数在另一个组中(不包括 5 的倍数)。

输入描述:
第一行是数据个数 N,第二行是输入的数据。

输出描述: 1 或 0。

样例
输入:
4
-3 5 -5 3
输出:
1

题解

首先将符合第二个条件的分别加起来,求差,其他的存入数组排序,然后从大的开始,开始累加减,加或者减,受与差的相反数和累加减结果的大小的影响。

代码

#include <iostream>
#include <cmath>

using namespace std;

int num[1000];

int main(int argc, const char * argv[])
{
    int N;
    cin >> N;
    int n;
    int key = 0;
    int sum_5 = 0;
    int sum_3 = 0;

    for (int i = 0; i < N; i++)
    {
        cin >> n;
        if (n % 5 == 0)
        {
            sum_5 += n;
        }
        else if (n % 3 == 0)
        {
            sum_3 += n;
        }
        else
        {
            num[key++] = n;
        }
    }

    for (int i = 0; i < key - 1; i++)
    {
        for (int j = i + 1; j < key; j++)
        {
            if (fabs(num[i]) > fabs(num[j]))
            {
                swap(num[i], num[j]);
            }
        }
    }

    int dif = sum_5 - sum_3;
    int res = 0;
    while (key)
    {
        if (res > -dif)
        {
            if (num[key - 1] > 0)
            {
                res -= num[key - 1];
            }
            else
            {
                res += num[key - 1];
            }
        }
        else
        {
            if (num[key - 1] > 0)
            {
                res += num[key - 1];
            }
            else
            {
                res -= num[key - 1];
            }
        }
        key--;
    }

    if (res == -dif)
    {
        cout << "1" << '\n';
    }
    else
    {
        cout << "0" << '\n';
    }
    return 0;
}

试题四 求二进制数字符串的和

描述

请编写程序,给定两个长度不超过 100 的二进制数字符串,计算它们的和,和也是字符串。例如,a = “1010”,
b = “1011”,和为”10101”。注意:不能将二进制数转换为十进制数进行计算,因为当字符串太长时,会溢出。

输入描述
两个二进制数字符串,中间以空格隔开。

输出描述
两个二进制数的和。

样例
输入:
1010 1011
输出:
10101

题解

一道基础的字符串和数学加法运算的问题,了解二进制加法的规则即可。细节问题需要注意一些。

代码

#include <iostream>
#include <string>

using namespace std;

char strA[101];
char A[101];
char strB[101];
char B[101];
char C[101];

void carry(int i)
{
    C[i] += 1;
    if (C[i] == '2')
    {
        C[i] = '0';
        carry(i + 1);
    }
    return ;
}

int main(int argc, const char * argv[])
{
    cin >> strA >> strB;
    int keyA = 0;
    int keyB = 0;
    int lenA = (int)strlen(strA);
    int lenB = (int)strlen(strB);
    for (int i = lenA - 1; i >= 0; i--)
    {
        A[keyA++] = strA[i];
//        cout << A[keyA - 1];
    }
//    cout << endl;

    for (int i = lenB - 1; i >= 0; i--)
    {
        B[keyB++] = strB[i];
//        cout << B[keyB - 1];
    }
//    cout << endl;

    for (int i = 0; i < keyA + keyB; i++)
    {
        C[i] = '0';
//        cout << C[i];
    }
//    cout << endl;
    int MAX = keyA > keyB ? keyA : keyB;
    int MIN = keyA < keyB ? keyA : keyB;
    for (int i = 0; i < MAX; i++)
    {
        if (i < MIN)
        {
            if (A[i] + B[i] - '0' - '0' == 1)
            {
                C[i] += 1;
            }
            else if (A[i] + B[i] - '0' - '0' == 2)
            {
                carry(i + 1);
            }
            if (C[i] > '1')
            {
                C[i] = '0';
                carry(i + 1);
            }
        }
        else
        {
            if (keyA > keyB)
            {
                if (A[i] - '0' == 1)
                {
                    C[i] += 1;
                }
                if (C[i] > '1')
                {
                    C[i] = '0';
                    carry(i + 1);
                }
            }
            else
            {
                if (B[i] - '0' == 1)
                {
                    C[i] += 1;
                }
                if (C[i] > '1')
                {
                    C[i] = '0';
                    carry(i + 1);
                }
            }
        }
    }
    int lenC = (int)strlen(C);

    bool f = false;

    for (int i = lenC - 1; i >= 0; i--)
    {
        if (C[i] != '0')
        {
            f = true;
        }
        if (f)
        {
           cout << C[i];
        }
    }
    std::cout << '\n';
    return 0;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值