2016码农谷全国大学生程序设计邀请赛(第一轮资格赛)

来源:互联网 发布:java中属性是什么 编辑:程序博客网 时间:2024/05/19 14:39

ACM模版

额,这次有些尴尬了,题虽然不难,但是睡过了四十五分钟,着实有些慌张,然后,做题就粗心了,少看了条件,最为尴尬的是,只能提交一次……

试题一 对码农的编程水平进行排名

描述

老码农要对N个码农的编程水平进行排序,这些码农的编号依次为1,2,3,…,N,但老码农无法获得他们的具体水平数据,只知道相对水平,例如,“P Q”表示P的水平比Q高。请编写程序,帮助老码农进行排序。
说明:符合条件的排序可能不是唯一的,此时要求输出时编号小的码农在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。

【输入说明】
第一行有2个数N、M,其中N(2<=N<=50)表示码农的个数,M表示接下来有M行输入数据。
接下来的M行数据中,每行也有2个数P、Q,表示P的水平比Q高。
同一行中的数之间用一个空格隔开。

【输出说明】
给出一个符合要求的排名顺序,码农之间用一个空格隔开,最后一个码农的后面没有空格。

样例
输入:
4 3
1 2
2 3
4 3
输出:
1 2 4 3

题解

思路很清晰,需要用到链表,在插入链表前,需要先进行一些条件的排序。(刚转C++一个月,还没有使用过链表呢,对链表的方法太陌生,使用方法都是百度的)

代码

#include <iostream>#include <list>using namespace std;typedef list<int> LISTINT;int p[100];int q[100];int a[100];int main(int argc, const char * argv[]){    LISTINT listPeople;    LISTINT::iterator it;    int N, M;    int P, Q;    cin >> N >> M;    int key = 0;    while (M--)    {        cin >> P >> Q;        p[key] = P;        q[key++] = Q;    }    for (int i = 0; i < key - 1; i++)    {        for (int j = i + 1; j < key; j++)        {            if (p[i] > p[j])            {                swap(p[i], p[j]);                swap(q[i], q[j]);            }            else if (p[i] == p[j] && q[i] < q[j])            {                swap(p[i], p[j]);                swap(q[i], q[j]);            }        }    }    listPeople.push_back(p[0]);    listPeople.push_back(q[0]);    int flag = key - 1;    while (flag)    {    l:        for (int i = 1; i < key; i++)        {            if (p[i] != 0)            {                for (it = listPeople.begin(); it != listPeople.end(); it++)                {                    if (*it == q[i])                    {                        listPeople.insert(it, p[i]);                        p[i] = 0;                        flag--;                        goto l;                    }                    else if (*it == p[i])                    {                        listPeople.insert(++it, q[i]);                        it--;                        p[i] = 0;                        flag--;                        goto l;                    }                }            }        }    }    int k = 0;    for (it = listPeople.begin(); it != listPeople.end(); it++)    {        a[k++] = *it;    }    for (int i = 0; i < k - 1; i++)    {        cout << a[i] << ' ';    }    cout << a[k - 1] << '\n';    free(&it);    free(&listPeople);    return 0;}

试题二 奇怪的数字:6174

描述

任意一个四位数的正整数A,其各个数位上的数字不全相同。如果将其各个数位上的数字重新排列,从所有排列中抽取出最大的数(M)和最小的数(N),然后将这两个数相减(M-N)。重复这个过程,最多经过七步,一定会得到6174。
注意:如果某位数出现0,则允许将0放在最左边组成4位数,例如:如果某步骤得到的数为1000,则有1000-0001=999,此时再次组合的最大数为9990,最小数为0999。
请编写程序,对于输入的一个4位数正整数,输出经过的步数。
要求:不得使用库函数进行排序,否则,人工审核时将判定程序无效。

【输入说明】
一个4位数的正整数A。 

【输出说明】
一个正整数(步数)。

样例
输入:
5652
输出:
4

题解

用字符串处理即可,水题。

代码

#include <iostream>using namespace std;char num[5];char numA[5];char numB[5];int main(int argc, const char * argv[]){    cin >> num;    int res = 0;    while ((num[0] - '0') * 1000 + (num[1] - '0') * 100 + (num[2] - '0') * 10 + (num[3] - '0') != 6174)    {        res++;        for (int i = 0; i < 3; i++)        {            for (int j = i + 1; j < 4; j++)            {                if (num[i] > num[j])                {                    swap(num[i], num[j]);                }            }        }        int MAX = (num[3] - '0') * 1000 + (num[2] - '0') * 100 + (num[1] - '0') * 10 + (num[0] - '0');        int MIN = (num[0] - '0') * 1000 + (num[1] - '0') * 100 + (num[2] - '0') * 10 + (num[3] - '0');        int dif = MAX - MIN;        num[3] = dif % 10 + '0';        dif /= 10;        num[2] = dif % 10 + '0';        dif /= 10;        num[1] = dif % 10 + '0';        dif /= 10;        num[0] = dif + '0';    }    cout << res << '\n';    return 0;}

试题三 将一个英文语句以单词为单位逆序排序

描述

请编写程序,将一个英文语句以单词为单位逆序排序,且每个单词中字母也逆序排列,然后输出。例如“I am ma nong gu”,逆序排列后为“ug gnon am ma I”。
要求:不得使用库函数进行排序,否则,人工审核时将判定程序无效。

【输入说明】
第一行为1个整数N(2< N <20),代表英文语句中单词的个数。
第二行是1个英文语句,每个单词的长度不超过15个字符,单词之间用1个空格隔开。语句中除了英文字母外,不再包含其他字符。

【输出说明】
输出为一行,所有单词之间用1个空格隔开。

样例
输入:
5
I am ma nong gu
输出:
ug gnon am ma I

题解

感觉是一道侮辱智商的题……

代码

#include <iostream>#include <cstring>using namespace std;char word[22][16];int main(int argc, const char * argv[]){    int N;    cin >> N;    for (int i = 0; i < N; i++)    {        cin >> word[i];    }    for (int i = N - 1; i > 0; i--)    {        int len = (int)strlen(word[i]);        for (int j = len - 1; j >= 0; j--)        {            cout << word[i][j];        }        cout << ' ';    }    int len = (int)strlen(word[0]);    for (int j = len - 1; j >= 0; j--)    {        cout << word[0][j];    }    cout << '\n';    return 0;}

试题四 小码农挑选资源的方案数

描述

小码农今天过生日,老码农带他到码农谷购买学习资源作为生日礼物,老码农告诉他,今天可以在码农谷选购3个学习资源,但这3个资源必须满足条件:3个资源的价格之和等于所有资源价格之和的一半。例如,如果有5个资源的价格分别是14、13、8、9、10,则小码农挑选资源的方案只有一种:(8,9,10)。
请编写程序,帮助小码农计算挑选资源的方案数,如果有符合条件的方案,则输出方案的数量;如果没有符合条件的方案,则输出0。

【输入说明】
第一行是一个整数N(N<100),表示待选资源的总数。
第二行有N个整数,每个整数之间用空格隔开,分别表示每个资源的价格(价格<50)。

【输出说明】
1个整数,表示挑选礼物的方案数,或者0。

【输入样例】
5
14 13 8 9 10

【输出样例】
1

题解

这里如果没有要求只能选择三本的话,含金量会提高些许,因为这样子最直观的就是用递归了。可是一提到只能选择三本,所以用三层for循环即可,一下子水到了极点……

代码

#include <iostream>using namespace std;int N;int sum = 0;int res = 0;int price[101];int flag[101] = {0};void solve(int n, int s, int q){    if (n < N && s == sum / 2 && q == 1)    {        res++;        return ;    }    if (n == N || s > sum / 2 || q == 1)    {        return ;    }    solve(n + 1, s + price[n], q--);    solve(n + 1, s, q);    return ;}int main(int argc, const char * argv[]){    cin >> N;    for (int i = 0; i < N; i++)    {        cin >> price[i];        sum += price[i];    }    solve(0, 0, 3);    cout << res << '\n';    return 0;}
0 0
原创粉丝点击