算法竞赛入门经典(第一版) 第五章 解题报告

算法竞赛入门经典(第一版) 第五章 解题报告

一、字符串题目

A - Palindromes

题意:

代码:

B - Where's Waldorf?

题意:

代码:

C - Automatic Poetry

题意:

给出一个字符串,字符串里面被<><>这4个字符分成了4个部分,比如题干的s1<s2>s3<s4>s5;

然后又有一个字符串,使用...,并且保证为...在最后面,我们假设这个字符串除了...以外的部分叫做T

题目意思就是输出T s4 s3 s2 s5   (Ps:空格只是为了好识别)

我使用了C风格的字符串直接读写,检测一下<><>这几个符号就好!

代码:

const int maxn = 110;

char s1[maxn], s2[maxn];
char tmp2[maxn], tmp3[maxn], tmp4[maxn], tmp5[maxn];

int main()
{
#ifdef LOCAL
    ///freopen("in.txt", "r", stdin);
    ///freopen("out.txt", "w", stdout);
#endif // LOCAL
    int t;
    scanf("%d", &t);
    getchar();
    while(t--)
    {
        gets(s1);
        gets(s2);

        int len = strlen(s1);
        int flag_1 = 0;
        int flag_2 = 0;
        int k2 = 0, k3 = 0, k4 = 0, k5 = 0;

        for(int i = 0; i < len; ++i)
        {
            if (s1[i] == '<' && flag_1 == 0)
            {
                int pos = i + 1;
                while(s1[pos] != '>')
                {
                    tmp2[k2++] = s1[pos++];
                }
                flag_1 = 1;
            }
            else if (s1[i] == '<' && flag_1 == 1)
            {
                int pos = i + 1;
                while(s1[pos] != '>')
                {
                    tmp4[k4++] = s1[pos++];
                }
            }
            else if (s1[i] == '>' && flag_2 == 0)
            {
                int pos = i + 1;
                while(s1[pos] != '<')
                {
                    tmp3[k3++] = s1[pos++];
                }
                flag_2 = 1;
            }
            else if (s1[i] == '>' && flag_2 == 1)
            {
                int pos = i + 1;
                while(s1[pos] != '\0')
                {
                    tmp5[k5++] = s1[pos++];
                }
            }
            if (s1[i] != '>' && s1[i] != '<')
                printf("%c", s1[i]);
        }
        printf("\n");
        tmp2[k2++] = '\0';
        tmp3[k3++] = '\0';
        tmp4[k4++] = '\0';
        tmp5[k5++] = '\0';

        int len2 = strlen(s2);

        for(int i = 0; i < len2; ++i)
        {
            if(s2[i] != '.')
                printf("%c", s2[i]);
            else
            {
                printf("%s%s%s%s\n", tmp4, tmp3, tmp2, tmp5);
                break;
            }
        }
    }
    return 0;
}


D - Artificial Intelligence?

题意:

题干说了很多,实际就是读取P U I这三个关键。读取其中2个 计算另外一个

区分题干和数据的方法就是'=‘这个字符,我只要检测到这个字符,然后看一看这个字符的前一个是啥,我就能知道最终我要计算的量

然后是读取空格之后的实数部分和单位的前缀部分

这里我使用了一个函数,double atof (char *)  这个函数能自动识别字符串的实数。具体细节百度!

坑点:如果不使用atof记得检查有没有’-‘ 这个哦  毕竟实数也包括负数!!!

代码:

const int maxn = 100000;
char s[maxn];


double check(int pos)
{
    int now = pos;
    double num;

    while(!isalpha(s[now]))
    {
        now++;
    }

    if (s[now] == 'm')
        return  0.001;
    else if(s[now] == 'k')
        return 1000.0;
    else if (s[now] == 'M')
        return  1000000.0;
    else
        return 1.0;
}

int main()
{
#ifdef LOCAL
    ///freopen("in.txt", "r", stdin);
    ///freopen("out.txt", "w", stdout);
#endif // LOCAL
    int t;
    int Ca = 1;

    scanf("%d\n", &t);
    getchar();
    while(t--)
    {
        double P, U, I;
        bool flag[3];
        memset(flag, false, sizeof(flag));

        gets(s);
        int len = strlen(s);
        for(int i = 0; i < len; ++i)
        {
            if (s[i] == '=' && s[i - 1] == 'P')
            {
                flag[0] = true;
                P = atof(&s[i + 1]) * check(i);

            }
            else if (s[i] == '=' && s[i - 1] == 'U')
            {
                flag[1] = true;
                U = atof(&s[i + 1])  * check(i);
            }
            else if (s[i] == '=' && s[i - 1] == 'I')
            {
                flag[2] = true;
                I = atof(&s[i + 1])  * check(i);
            }
        }

        printf("Problem #%d\n",Ca++);
        if (!flag[0])
        {
            printf("P=%.2lfW\n\n", U * I);
        }
        else if (!flag[2])
        {
            printf("I=%.2lfA\n\n", P / U);
        }
        else
        {
            printf("U=%.2lfV\n\n", P / I);
        }
    }
    return 0;
}


E - Excuses, Excuses!

题意:

代码:

F - Decode the tape

题意:

代码:

G - Andy's First Dictionary

题意:

在一篇文章中,整理出其中的单词,并升序输出。

注意要全部小写,且输出一个单词即可!


比如

a after A

输出应该是

a

after

然后莫名的冲动用了STL的set 外加getchar()一个一个的读入

代码:

int main()
{
#ifdef LOCAL
    ///freopen("in.txt", "r", stdin);
    ///freopen("out.txt", "w", stdout);
#endif // LOCAL
    char c;
    set<string> s;
    string tmp;

    while((c = getchar()) != EOF)
    {
        if (!isalpha(c))
        {
            if (tmp.size())
            {
                s.insert(tmp);
                tmp.erase();
            }
        }
        else
        {
            tmp.push_back(tolower(c));
        }
    }
    if (tmp.size())
        s.insert(tmp);

    for(set<string>::iterator i = s.begin(); i != s.end(); ++i)
        cout << *i << endl;

    return 0;
}


H - Immediate Decodability

题意:

给出一个有01组成的二进制集合,题目要求检查这个集合里面每个元素是否是前一个元素的前缀,如果有任何一个元素,作为了其他元素的前缀,就输出

is not immediately decodable
否则输出

is immediately decodable
具体这个有啥用,我也不知道。这道题最快的办法就是用 string 里面的 find函数,看看能不能 返回0, 如果返回0就表示是前缀

代码:

const int maxn = 1000;

string code[maxn];

int main()
{
#ifdef LOCAL
    ///freopen("in.txt", "r", stdin);
    ///freopen("out.txt", "w", stdout);
#endif // LOCAL
    string tmp;
    int k = 0;
    int Ca = 1;
    while(cin >> tmp)
    {

        if (tmp == "9")
        {
            bool flag = false;
            for(int i = 0; i < k && !flag; ++i)
                for(int j = i + 1; j < k  && !flag; ++j)
                    if(code[i].find(code[j]) == 0 || code[j].find(code[i]) == 0)   //第i个和第j个元素,要互相查找一下
                        flag = true;
            if (!flag)
                cout << "Set " << Ca++ << " is immediately decodable" << endl;
            else
                cout << "Set " << Ca++ <<" is not immediately decodable" << endl;
            k = 0;
        }
        else
            code[k++] = tmp;
    }
    return 0;
}


I - Automatic Editing

题意:

说了很多细节,其实就和我们的文本编辑器的查找再替换是一个样。所以输入的相当于是查找的值和替换的值。

有一个需要注意的地方,那就是,查找与替换必须把一组关键词用到不能用了为止,然后才能试用下一组

这里使用了C++的来写这道题

使用string的replace函数,这是一个重载函数,我使用的是这个版本——》 replace(原字符串位置,替换字符串长度,替换字符串);

这道题目暂时没有发现坑点!

代码:

int main()
{
#ifdef LOCAL
    ///freopen("in.txt", "r", stdin);
    ///freopen("out.txt", "w", stdout);
#endif // LOCAL
    int t;
    string tmp, key;

    while(cin >> t && t)
    {
        vector<string> pwd1;
        vector<string> pwd2;
        cin.ignore();           //偷学的 据说可以和getchar()等效

        for(int i = 1; i <= 2 * t; ++i)
        {
            getline(cin, tmp);

            if (i & 1)
                pwd1.push_back(tmp);
            else
                pwd2.push_back(tmp);
        }

        getline(cin, key);

        for(int k = 0; k < t; ++k)
        {
            int pos;

            while((pos = key.find(pwd1[k])) != string::npos)   //根据规则 必须查找替换到,当前关键词无法使用为止
            {
                key.replace(pos, pwd1[k].size(), pwd2[k]);
            }
        }
        cout << key << endl;

    }
    return 0;
}



你可能感兴趣的:(算法,代码,字符串,ACM,解题报告)