第二周

作业

第一题 Maze

题意

在一个5* 5的迷宫中从(0,0)走到(4,4),迷宫直接通过5*5的二维数组给出,0为可走,1为不可走。找到最短路径。

思路

可以使用BFS算法来求解,同时声明2个二维数组lx,ly,已记录每个节点被遍历过来前驱点x,y坐标。BFS起始节点为(0,0),当遍历到目标节点后,迭代lx,ly找到最短的路径,倒序输出完成。

代码
#include <iostream>
#include <queue>
using namespace std;

int x[4] = {1, -1, 0, 0};
int y[4] = {0, 0, 1, -1};
struct point
{
    int x0;
    int y0;
    point(int xo, int yo)
    {
        x0 = xo;
        y0 = yo;
    }
};
int main()
{
    int l[5][5];
    int lx[5][5];
    int ly[5][5];
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            cin >> l[i][j];
            lx[i][j] = 0;
            ly[i][j] = 0;
        }
    }

    queue<point> q;
    int a = 0;
    int b = 0;
    l[0][0] = 1;
    point p(a, b);
    q.push(p);
    while (!q.empty())
    {
        point p2 = q.front();
        q.pop();
        int nx = p2.x0;
        int ny = p2.y0;
        for (int i = 0; i < 4; i++)
        {
            int a = nx + x[i];
            int b = ny + y[i];
            if (0 <= a && a <= 4 && b >= 0 && b <= 4)
            {
                if (l[a][b] != 1)
                {
                    l[a][b] = 1;
                    p.x0 = a;
                    p.y0 = b;
                    q.push(p);
                    lx[a][b] = nx;
                    ly[a][b] = ny;
                }
            }
        }
    }
    int num = 1;
    int m[1000];
    int n[1000];
    int w, e;
    w = 4;
    e = 4;
    m[0] = w;
    n[0] = e;
    while (!(w == 0 && e == 0))
    {
        int w2 = lx[w][e];
        int e2 = ly[w][e];
        w = w2;
        e = e2;
        m[num] = w;
        n[num] = e;
        num++;
    }
    for (int i = num - 1; i >= 0; i--)
    {
        cout << "(" << m[i] << ", " << n[i] << ")" << endl;
    }
}

第二题

题意

有A、B两个杯子,每个杯子可以进行装满、倒空、倒入另一个杯这三种操作,最后使杯中含有C单位的水。输入直接为A、B、C三个数字,表示A、B两个杯子和要求的C单位水。其中A<=B,C<=B。

思路

若要求最少操作步骤,则要使用隐式图的BFS,但由于题目没有要求最少的操作步骤,可以使用简单的方法。
由于A,B互质,所以对于任意C,存在x,使得(x*B)%A=C。所以可以模拟这个过程。将B倒满水后,向A中倒水,如果A中水满了,则将A杯倒空;如果B空,则倒满B。当B中水等于C时,结束。

#include <stdio.h>
void doo(int va, int vb, int c)
{
    int a = 0;
    int b = 0;
    while (b != c)
    {
        if (b == 0)
        {
            b = vb;
            printf("fill B\n");
        }
        else if (b < va - a)
        {
            a += b;
            b = 0;
            printf("pour B A\n");
        }
        else
        {
            b = b - (va - a);
            a = 0;
            printf("pour B A\n");
            if (b != c)
                printf("empty A\n");
        }
    }
    printf("success\n");
}
int main()
{
    int va, vb, c;
    while (scanf("%d%d%d", &va, &vb, &c) != EOF)
        doo(va, vb, c);
}

实验

A

题意

判断烷烃基的种类,每一次输入五组数对,代表六个原子间的连接方式。根据输入判断烷烃基的种类。

分析

分析五种同分异构体,发现只有2-methylpentane 和3-methylpentane每个原子与其他原子的连接个数相同。因此,解决过程分为两步。第一步,声明一位数组,存储每个原子的临接原子的数目,并排序,如果对应n-hexane、2,3-dimethylbutane、2,2-dimethylbutane的情况,可直接判断好,如果对应2-methylpentane 、3-methylpentane的情况,则进行下一步。记录下有两个临接原子的标号a,b,如果a与b临接,则为2-methylpentane;反之为3-methylpentane。

代码
#include <algorithm>
#include <iostream>
using namespace std;

int a2[4][6] = {
    {1, 1, 2, 2, 2, 2},
    {1, 1, 1, 2, 2, 3},
    {1, 1, 1, 1, 3, 3},
    {1, 1, 1, 1, 2, 4},
};

string jie[4]{"n-hexane", "2-methylpentane 3-methylpentane", "2,3-dimethylbutane", "2,2-dimethylbutane"};
void doo()
{
    int a[5];
    int b[5];
    int find[2];
    int num = 0;
    for (int i = 0; i < 5; i++)
    {
        cin >> a[i] >> b[i];
    }

    int ans[6];
    for (int i = 0; i < 6; i++)
    {
        ans[i] = 0;
    }
    for (int i = 0; i < 5; i++)
    {
        ans[a[i] - 1]++;
        ans[b[i] - 1]++;
    }
    for (int i = 0; i < 6; i++)
    {
        if (ans[i] == 2)
        {
            find[num] = i + 1;
            num++;
        }
    }
    sort(ans, ans + 6);
    bool d = 0;
    for (int i = 0; i < 4; i++)
    {
        d = 0;
        for (int j = 0; j < 6; j++)
        {
            if (ans[j] != a2[i][j])
            {
                d = 1;
            }
        }
        if (d == 0)
        {
            if (i != 1)
            {
                cout << jie[i] << endl;
            }
            else
            {
                bool dp = 0;
                for (int i = 0; i < 5; i++)
                {
                    if (a[i] == find[0] && b[i] == find[1])
                    {
                        cout << "2-methylpentane" << endl;
                        dp = 1;
                    }
                    else
                    {
                        if (a[i] == find[1] && b[i] == find[0])
                        {
                            cout << "2-methylpentane" << endl;
                            dp = 1;
                        }
                    }
                }
                if (!dp)
                {
                    cout << "3-methylpentane" << endl;
                }
            }
        }
    }
}

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        doo();
    }
}

B

题意

输入第一行为n,m,n为题目数量,m为单位罚时。
接下来每一行有m+1列,第一列为name,以后m列为分数。分数有3种情况,第一种为0,代表还没做;第二种为负数,代表出错的次数(还未通过);第三种,一个整数,代表通过所用时间,可能有一个括号,代表出错的次数,计入罚时。

分析

声明string[n+1],类型记录每一个选手的名字和以后每道题的信息。处理每一个string的首字符,如果为0-9之间的数字,则AC数加一。对每一个通过的字符串,使用循环处理成整形数据。如果有括号,则将括号中的数据处理成整形数据。

处理好每个选手的信息后,重载比较,利用sort函数排序,输出。

代码
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

class p
{
public:
    int s;
    int t;
    string n;
};
bool compare(const p &u, const p &c)
{
    if (c.s != u.s)
    {
        return (u.s < c.s);
    }
    else
    {
        if (u.t != c.t)
        {
            return (u.t > c.t);
        }
        else
        {
            return (u.n > c.n);
        }
    }
}
void doo(const int ops, p *ans, int n, int m, string *a)
{
    int atime = 0;
    int act = 0;
    int s = 0;
    for (int i = 1; i < n + 1; i++)
    {
        if (a[i][0] != '-' && a[i][0] != '0')
        {
            s++;
            int j = 0;
            int time = 0;
            int ct = 0;
            while (j < a[i].length())
            {
                if (a[i][j] != '(')
                {
                    time = time * 10 + a[i][j] - 48;
                }
                else
                {
                    break;
                }
                j++;
            }
            atime += time;
            if (j != a[i].length())
            {
                j++;
                while (a[i][j] != ')')
                {
                    ct = ct * 10 + a[i][j] - 48;
                    j++;
                }
                act += ct;
            }
        }
    }
    ans[ops].n = a[0];
    ans[ops].s = s;
    ans[ops].t = atime + act * m;
}
int main()
{
    int n, m;
    p ans[1000];
    cin >> n >> m;
    string a[n + 1];
    int ops = 0;
    while (cin >> a[0])
    {
        for (int i = 1; i < n + 1; i++)
        {
            cin >> a[i];
        }
        doo(ops, ans, n, m, a);
        ops++;
    }
    sort(ans, ans + ops, compare);
    for (int i = ops - 1; i >= 0; i--)
    {
        char *pq = (char *)ans[i].n.c_str();
        printf("%-10s %2d %4d\n", pq, ans[i].s, ans[i].t);
    }
}

C

题意

简单模拟。
模拟打牌,只是模拟发牌之后的排牌过程,多组数据,以#结尾。
输入

CTCAH8CJD4C6D9SQC7S5HAD2HJH9CKD3H6D6D7H3HQH4C5DKHKS9
SJDTS3S7S4C4CQHTSAH2D8DJSTSKS2H5D5DQDAH7C9S8C8S6C2C3

对于一组数据,第一行为N、E、S、W四种之一,表示由哪个方向的玩家进行发牌,发牌第一张是发给下家而不是自己,一个注意的点。之后两行,每行52个字符,表示26张排,一张拍的表示为两个字符,如CT,C表示梅花,T表示10,。
要求按照一定顺序将四个人的手牌排序,题目定义牌的顺序介绍:首先,花色是(梅花)<(方片)<(黑桃)<(红桃),(输入时,用C,D,S,H分别表示梅花,方片,黑桃,红桃)。对于牌面的值,我们规定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。 即先按花色排大小,同花色按牌面排序。
输出,多组数据之间有一个空行,对于一组数据,从South player:的牌开始按顺序输出,具体形式如下:

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|
+---+---+---+---+---+---+---+---+---+---+---+---+---+
思路

每次读入分成两行,每一张牌由两个字符组成,第一个代表花色,第二个代表数字。定义p类型,扑克牌。声明p[4][13]二维数组。利用循环及取模将内容输入。
读入完成后,进行排序。声明常量数组,将花色和数组按顺序写进常量数组中。对花色和数字的大小比较变为对常量数组中下标的比较。重载p类型的比较函数,sort排序,按规定输出就好了。

代码
#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;

char f[4] = {'C', 'D', 'S', 'H'};
char s[13] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
char fangxiang[4] = {'S', 'W', 'N', 'E'};
string player[4] = {"South player:", "West player:", "North player:", "East player:"};

class p
{
public:
    char a; //花色
    char b; //数字2
};
bool compare(const p &u, const p &c)
{
    int f1, f2;
    for (int i = 0; i < 4; i++)
    {
        if (u.a == f[i])
        {
            f1 = i;
        }
        if (c.a == f[i])
        {
            f2 = i;
        }
    }
    if (f1 != f2)
    {
        return (f1 < f2);
    }
    else
    {
        int s1, s2; //记录数字
        for (int i = 0; i < 13; i++)
        {
            if (u.b == s[i])
            {
                s1 = i;
            }
            if (c.b == s[i])
            {
                s2 = i;
            }
        }
        return s1 < s2;
    }
}
void doo(char pep)
{

    string s1;
    string s2;
    cin >> s1;
    cin >> s2;
    s1 += s2;
    int num = 0;
    for (int i = 0; i < 4; i++)
    {
        if (pep == fangxiang[i])
        {
            num = i;
            break;
        }
    }
    num = (num + 1) % 4;
    p all[4][13];
    for (int i = 0; i < 104; i = i + 2)
    {
        int j = i / 2;
        int x = j / 4;
        int y = (j + num) % 4;
        all[y][x].a = s1[i];
        all[y][x].b = s1[i + 1];
    }
    for (int i = 0; i < 4; i++)
    {
        sort(all[i], all[i] + 13, compare);
    }
    for (int i = 0; i < 4; i++)
    {
        cout << player[i] << endl;
        cout << "+---+---+---+---+---+---+---+---+---+---+---+---+---+" << endl;
        for (int j = 0; j < 13; j++)
        {
            cout << "|" << all[i][j].b << " " << all[i][j].b;
        }
        cout << "|" << endl;
        for (int j = 0; j < 13; j++)
        {
            cout << "|"
                 << " " << all[i][j].a << " ";
        }
        cout << "|" << endl;
        for (int j = 0; j < 13; j++)
        {
            cout << "|" << all[i][j].b << " " << all[i][j].b;
        }
        cout << "|" << endl;
        cout << "+---+---+---+---+---+---+---+---+---+---+---+---+---+" << endl;
    }
    cout << endl;
}

int main()
{
    char pep;
    cin >> pep;
    while (pep != '#')
    {
        doo(pep);
        cin >> pep;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值