程序设计思维与实践 Week2 实验 (3/4/数据班)

·A - 化学 (编译器选 GNU G++)

原题目如下

化学很神奇,以下是烷烃基。

 

 假设如上图,这个烷烃基有6个原子和5个化学键,6个原子分别标号1~6,然后用一对数字 a,b 表示原子a和原子b间有一个化学键。这样通过5行a,b可以描述一个烷烃基

你的任务是甄别烷烃基的类别。

原子没有编号方法,比如
1 2
2 3
3 4
4 5
5 6

1 3
2 3
2 4
4 5
5 6
是同一种,本质上就是一条链,编号其实是没有关系的,可以在纸上画画就懂了Input

输入第一行为数据的组数T(1≤T≤200000)。每组数据有5行,每行是两个整数a, b(1≤a,b≤6,a ≤b),数据保证,输入的烷烃基是以上5种之一

Output

每组数据,输出一行,代表烷烃基的英文名

Example

Input

2

1 2

2 3

3 4

4 5

5 6

1 4

2 3

3 4

4 5

5 6

Output

n-hexane

3-methylpentane

问题分析:

从化学角度找规律,是比较容易的。有i个碳碳键的原子数目可以很好的统计出来,比如,3-methylpentane中,3个原子有1个碳碳键,2个原子有2个碳碳键,中间1个原子有1个碳碳键。考虑到这点性质和2-methylpentane一样,但是和剩下的三个都不一样,而且剩下的三个各不一样,所以接下来区分2-methylpentane和2-methylpentane。

显然可以记录含3个碳碳键的碳原子及与其相邻的碳原子。对于2-methylpentane来说,与它相邻的碳原子,有2个含1个碳碳键,有1个含两个碳碳键。

 

#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i)
    {
        int num_key[5];//有i个键的原子的数目
        for (int p = 0; p < 5; ++p)
            num_key[p] = 0;
        int atom_key[7];//第i的原子的键的数目,i=1,2,...,6
        for (int p = 0; p < 7; ++p)
            atom_key[p] = 0;

        int matrix[7][7];
        for (int p = 0; p < 7; ++p)
            for (int q = 0; q < 7; ++q)
                matrix[p][q] = 0;
        int a, b;
        for (int j = 0; j < 5; ++j)
        {
            cin >> a >> b;
            matrix[a][b] = 1;
            matrix[b][a] = 1;
            atom_key[a]++;
            atom_key[b]++;
        }

        for (int r = 1; r <= 6; ++r)
        {
            if (atom_key[r] == 1)
                num_key[1]++;
            else if (atom_key[r] == 2)
                num_key[2]++;
            else if (atom_key[r] == 3)
                num_key[3]++;
            else if (atom_key[r] == 4)
                num_key[4]++;
        }
        
        if (num_key[1] == 2 && num_key[2] == 4)
            cout << "n-hexane" << endl;
        else if (num_key[1] == 3 && num_key[2] == 2 && num_key[3] == 1)
        {
            int atom_key3;
            for (int w = 1; w <= 6; ++w)
                if (atom_key[w] == 3)
                    atom_key3 = w;
            int temp1 = 0;
            int temp2 = 0;
            for (int u = 1; u <= 6; ++u)
            {
                if (matrix[atom_key3][u] == 1)
                {
                    if (atom_key[u] == 1)
                        temp1++;
                    else if (atom_key[u] == 2)
                        temp2++;
                }
            }
            if (temp1 == 2)
                cout << "2-methylpentane" << endl;
            else
                cout << "3-methylpentane" << endl;
        }
        else if (num_key[1] == 4 && num_key[2] == 0 && num_key[3] == 2)
            cout << "2,3-dimethylbutane" << endl;
        else if (num_key[1] == 4 && num_key[2] == 1 && num_key[4] == 1)
            cout << "2,2-dimethylbutane" << endl;
    }
    return 0;
}

·B - 爆零(×)大力出奇迹(√)

原题目如下

程序设计思维作业和实验使用的实时评测系统,具有及时获得成绩排名的特点,那它的功能是怎么实现的呢?
我们千辛万苦怼完了不忍直视的程序并提交以后,评测系统要么返回AC,要么是返回各种其他的错误,不论是怎样的错法,它总会给你记上一笔,表明你曾经在这儿被坑过,而当你历经千辛终将它AC之后,它便会和你算笔总账,表明这题共错误提交了几次。
在岁月的长河中,你通过的题数虽然越来越多,但通过每题时你所共花去的时间(从最开始算起,直至通过题目时的这段时间)都会被记录下来,作为你曾经奋斗的痕迹。特别的,对于你通过的题目,你曾经的关于这题的每次错误提交都会被算上一定的单位时间罚时,这样一来,你在做出的题数上,可能领先别人很多,但是在做出同样题数的人中,你可能会因为罚时过高而处于排名上的劣势。
例如某次考试一共八道题(A,B,C,D,E,F,G,H),每个人做的题都在对应的题号下有个数量标记,负数表示该学生在该题上有过的错误提交次数但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上了一对括号,里面有个正数b,则表示该学生AC了这道题,耗去了时间a,同时曾经错误提交了b次。例子可见下方的样例输入与输出部分。

Input输入数据包含多行,第一行是共有的题数n(1≤n≤12)以及单位罚时m(10≤m≤20),之后的每行数据描述一个学生的信息,首先是学生的用户名(不多于10个字符的字串)其次是所有n道题的得分现状,其描述采用问题描述中的数量标记的格式,见上面的表格。
Output根据这些学生的得分现状,输出一个实时排名。实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。
Sample Input

8 20
GuGuDong  96     -3    40(3) 0    0    1      -8    0
hrz       107    67    -3    0    0    82     0     0
TT        120(3) 30    10(1) -3   0    47     21(2) -2
OMRailgun 0      -99   -8    0    -666 -10086 0     -9999996
yjq       -2     37(2) 13    -1   0    113(2) 79(1) -1
Zjm       0      0     57(5) 0    0    99(3)  -7    0

Sample Output

TT          5  348
yjq         4  342
GuGuDong    3  197
hrz         3  256
Zjm         2  316
OMRailgun   0    0

问题分析:

着重做以下三件事:

1,将参赛者的信息用结构体储存起来,包括姓名,ac数目,得分

2,读入数据,判断读入的格式,计算或者直接将相关信息填入结构体中

3,写排序规则,排序后输出

具体来说,比较难的是读入数据。使用助教的方法,用scanf从键盘读入字符串,然后用sscanf读字符串到指定变量,是最方便的,容易区分得分和罚时。我用的方法很繁琐,是分析、判断string,从string中读有效的数据。这一点需要注意。

#include <iostream>
#include <string>
#include <algorithm>
#include <iomanip>

using namespace std;

struct node
{
    string name;
    int ac = 0;
    int score = 0;
};

node stu[10005];
bool cmp(const node& x, const node& y)
{
    if (x.ac != y.ac)
        return x.ac > y.ac;
    else if (x.score != y.score)
        return x.score < y.score;
    else
        return x.name < y.name;
}
int main()
{
    int n, m;
    cin >> n >> m;
    int t = 0;
    while (cin >> stu[t].name)
    {
        stu[t].ac = 0; stu[t].score = 0;
        for (int i = 0; i < n; i++)
        {
            string info;
            cin >> info;
            if (info[0] == '-')
                continue;
            if (info[0] == '0')
                continue;
            stu[t].ac++;
            int len = info.length();
            int p, s = 0;

            for (p = 0; p < len; p++)
            {
                if (info[p] == '(') break;
                s = s * 10 + info[p] - '0';
            }
            stu[t].score += s;
            s = 0;
            if (p < len)
            {
                for (int k = p + 1; k < len - 1; k++)
                {
                    s = s * 10 + info[k] - '0';
                }
            }
            stu[t].score += s * m;
        }
        t++;
    }
    sort(stu, stu + t, cmp);       
    for (int i = 0; i < t; ++i)
    {
        cout << setiosflags(ios::left) << setw(10) << stu[i].name;
        printf_s(" %2d %4d
", stu[i].ac, stu[i].score);
    }
    return 0;
}

 ·C-瑞神打牌

 原题目如下

瑞神HRZ因为疫情在家闲得无聊,同时他又非常厉害,所有的课对他来说都是水一水就能拿A+,所以他无聊,找来了另外三个人:咕咕东,腾神以及zjm来打牌(天下苦瑞神久矣)。
显然,牌局由四个人构成,围成一圈。我们称四个方向为北 东 南 西。对应的英文是North,East,South,West。游戏一共由一副扑克,也就是52张构成。开始,我们指定一位发牌员(东南西北中的一个,用英文首字母标识)开始发牌,发牌顺序为顺时针,发牌员第一个不发自己,而是发他的下一个人(顺时针的下一个人)。这样,每个人都会拿到13张牌。
现在我们定义牌的顺序,首先,花色是(梅花)<(方片)<(黑桃)<(红桃),(输入时,我们用C,D,S,H分别表示梅花,方片,黑桃,红桃,即其单词首字母)。对于牌面的值,我们规定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。
现在你作为上帝,你要从小到大排序每个人手中的牌,并按照给定格式输出。(具体格式见输出描述和样例输出)。

Input

输入包含多组数据
每组数据的第一行包含一个大写字符,表示发牌员是谁。如果该字符为‘#’则表示输入结束。
接下来有两行,每行有52个字符,表示了26张牌,两行加起来一共52张牌。每张牌都由两个字符组成,第一个字符表示花色,第二个字符表示数值。

Output

输出多组数据发牌的结果,每组数据之后需要额外多输出一个空行!!!!!
每组数据应该由24行的组成,输出按照顺时针方向,始终先输出South Player的结果,每位玩家先输出一行即玩家名称(东南西北),接下来五行,第一行和第五行输出固定格式(见样例),第二行和第四行按顺序和格式输出数值(见样例),第三行按顺序和格式输出花色(见样例)。

Sample Input

N
CTCAH8CJD4C6D9SQC7S5HAD2HJH9CKD3H6D6D7H3HQH4C5DKHKS9
SJDTS3S7S4C4CQHTSAH2D8DJSTSKS2H5D5DQDAH7C9S8C8S6C2C3
#

Sample Output

South player:
+---+---+---+---+---+---+---+---+---+---+---+---+---+
|6 6|A A|6 6|J J|5 5|6 6|7 7|9 9|4 4|5 5|7 7|9 9|T T|
| C | C | D | D | S | S | S | S | H | H | H | H | H |
|6 6|A A|6 6|J J|5 5|6 6|7 7|9 9|4 4|5 5|7 7|9 9|T T|
+---+---+---+---+---+---+---+---+---+---+---+---+---+
West player:
+---+---+---+---+---+---+---+---+---+---+---+---+---+
|2 2|5 5|9 9|K K|5 5|7 7|9 9|4 4|T T|J J|A A|8 8|A A|
| C | C | C | C | D | D | D | S | S | S | S | H | H |
|2 2|5 5|9 9|K K|5 5|7 7|9 9|4 4|T T|J J|A A|8 8|A A|
+---+---+---+---+---+---+---+---+---+---+---+---+---+
North player:
+---+---+---+---+---+---+---+---+---+---+---+---+---+
|3 3|4 4|J J|2 2|3 3|T T|Q Q|K K|8 8|Q Q|K K|2 2|3 3|
| C | C | C | D | D | D | D | D | S | S | S | H | H |
|3 3|4 4|J J|2 2|3 3|T T|Q Q|K K|8 8|Q Q|K K|2 2|3 3|
+---+---+---+---+---+---+---+---+---+---+---+---+---+
East player:
+---+---+---+---+---+---+---+---+---+---+---+---+---+
|7 7|8 8|T T|Q Q|4 4|8 8|A A|2 2|3 3|6 6|J J|Q Q|K K|
| C | C | C | C | D | D | D | S | S | H | H | H | H |
|7 7|8 8|T T|Q Q|4 4|8 8|A A|2 2|3 3|6 6|J J|Q Q|K K|
+---+---+---+---+---+---+---+---+---+---+---+---+---+

 问题分析

牌的顺序已经定下来了,只需要分发给四个玩家即可。使用简单的循环,用一个结构体数组代表一个玩家,每个结构体代表一张扑克,储存花色和大小,然后读入发牌顺序,从指定的玩家开始,顺时针依次发牌给玩家。

值得注意的是,单独写两个函数,一个是吧花色转化为整数,例如,按照规则,A最大,所以定为14,然后T,J,Q,K一次是10,11,12,13,其余数字转化为相应的整数就可以了。这样有利于排序。另一个函数正好相反,把储存的数转化为代表花色的字符,方便输出。

#include <iostream>
#include <algorithm>

using namespace std;

struct poker
{
    char type;
    int size;
};

poker player[4][13];//player[0] is in south, [1] in west, [2] in north, [3] in east

int char2size(const char& c)
{
    if (c >= '2' && c <= '9')
        return (c - '0');
    else if (c == 'A')
        return 14;
    else if (c == 'T')
        return 10;
    else if (c == 'J')
        return 11;
    else if (c == 'Q')
        return 12;
    else if (c == 'K')
        return 13;
    return -1;
}

char size2char(const int& c)
{
    if (c >= 2 && c <= 9)
        return (c + '0');
    else if (c == 14)
        return 'A';
    else if (c == 10)
        return 'T';
    else if (c == 11)
        return 'J';
    else if (c == 12)
        return 'Q';
    else if (c == 13)
        return 'K';
    return 0;
}

bool comp(const poker& p1, const poker& p2)
{
    int q1 = 0, q2 = 0;
    if (p1.type == 'C')
        q1 = 0;
    else if (p1.type == 'D')
        q1 = 1;
    else if (p1.type == 'S')
        q1 = 2;
    else if (p1.type == 'H')
        q1 = 3;

    if (p2.type == 'C')
        q2 = 0;
    else if (p2.type == 'D')
        q2 = 1;
    else if (p2.type == 'S')
        q2 = 2;
    else if (p2.type == 'H')
        q2 = 3;

    if (q1 != q2)
        return q1 < q2;
    else
        return p1.size < p2.size;
}

int main()
{
    char n;
    while (cin >> n && n != '#')
    {
        int start = 0;
        if (n == 'S')
            start = 1;
        else if (n == 'W')
            start = 2;
        else if (n == 'N')
            start = 3;
        else if (n == 'E')
            start = 0;
        string order;
        int i = start;
        int p[4] = { 0,0,0,0 };
        for (int r = 0; r < 2; ++r)
        {
            cin >> order;
            int len = order.length();
            int point = 0;
            for (i; point < len; )
            {
                player[i][p[i]].type = order[point++]; 
                player[i][p[i]].size = char2size(order[point++]);
                p[i]++;
                i += 1;
                i %= 4;
            }
        }

        for (int k = 0; k < 4; ++k)
        {
            sort(player[k], player[k] + 13, comp);
        }
        for (int k = 0; k < 4; ++k)
        {
            if (k == 0)
                cout << "South player:" << endl;
            else if (k == 1)
                cout << "West player:" << endl;
            else if (k == 2)
                cout << "North player:" << endl;
            else if (k == 3)
                cout << "East player:" << endl;


            for (i = 0; i < 13; ++i)
                cout << '+' << '-' << '-' << '-';
            cout <<'+'<< endl;

            for (i = 0; i < 13; ++i)
            {
                char c = size2char(player[k][i].size);
                cout << '|' << c << ' ' << c;
            }
            cout <<'|'<< endl;

            for (i = 0; i < 13; ++i)
                cout << '|' << ' ' << player[k][i].type << ' ';
            cout <<'|'<< endl;

            for (i = 0; i < 13; ++i)
            {
                char c = size2char(player[k][i].size);
                cout << '|' << c << ' ' << c;
            }
            cout << '|' << endl;

            for (i = 0; i < 13; ++i)
                cout << '+' << '-' << '-' << '-';
            cout << '+' << endl;
        }
        cout << endl;
    }
    return 0;
}

 

 

 

 

 

原文地址:https://www.cnblogs.com/master-cn/p/12411633.html