程序设计思维与实践 Week2限时大模拟

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

解题思路

通过观察各个烷烃基可以发现不同的每个烷烃基的碳原子化学键个数是不同的,其中能将其与其他烷烃基区别开的特点如下:
n-hexane:2个化学键个数为1的碳原子
2-methylpentane:3个化学键个数为1的碳原子,1个化学键个数为3的原子,且该化学键与1个化学键为2的原子相连接
3-methylpentane:3个化学键个数为1的碳原子,1个化学键个数为3的原子,且该化学键与2个化学键为2的原子相连接
2,3-dimethyibutane:4个化学键个数为1的碳原子
2,3-dimethyibutane:4个化学键个数为1的碳原子,1个化学键个数为4的碳原子

代码

#include<iostream>
using namespace std;
int main()
{
 int n;
 cin >> n;
 for (int i = 0; i < n; i++)
 {
  int state[7];//记录每个原子的化学键个数
  int num[7];//记录化学键个数为i的原子个数
  int node[7][7];//记录每个化学键
  int three_node[7];//记录有3个化学键的原子
  int number=0;//记录与有三个化学键的原子存在化学键且有两个化学键的原子个数
  memset(state, 0, sizeof(state));
  memset(num, 0, sizeof(num));
  memset(node, 0, sizeof(node));
  memset(three_node, 0, sizeof(three_node));
  for (int j = 0; j < 5; j++)
  {
   int a, b;
   cin >> a >> b;
   state[a]++;
   state[b]++;
   node[a][b]++;
   //cout << a << b << " ";
   //cout << state[a] << " " << state[b] << endl;
  }
  for (int k = 1; k < 7; k++)
  {
   num[state[k]]++;
   if (state[k] == 3)
    three_node[k] = k;
  }
  if (num[1] == 2)//含有2个化学键为1的原子
   cout << "n-hexane" << endl;
  else if (num[1] == 4)
  {
   if (num[4] == 1)//含有4个化学键为1的原子和1个化学键为4的原子
    cout << "2,2-dimethylbutane" << endl;
   else
    cout << "2,3-dimethylbutane" << endl;
  }
  else if (num[1] == 3)
  {
   for (int i = 1; i < 7; i++)
   {
    if (three_node[i] != 0)
    {
     for (int j = 1; j < 7; j++)
     {
      if ((node[i][j] != 0 || node[j][i] != 0) && state[j] == 2)
       number++;
     }
    }
   }
   if (number==1)//含有3个化学键为1的原子且1个化学键个数为3的原子,且该化学键与1个化学键为2的原子相连接
    cout << "2-methylpentane" << endl;
   else
    cout << "3-methylpentane" << endl;
  }
 }
}

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

解题思路

用结构体来表示每个参赛选手的各种情况:name名字,num做对的AC题数,time总用时,
遍历每个参赛选手的成绩,若为正且无括号则num++,time+正数;若为正且有括号则num++,且time+时间和罚时;若为负数,time+罚时,若为0都不变然后进行排序

代码

#include<iostream>
#include<cstring>
#include<algorithm>
#define Max 1000
using namespace std;
struct student
{
 char name[20];//名字
 int num;//AC的题数
 int time;//罚时
} s[Max];
bool comp(const student& a, const student& b)
{
 if (a.num != b.num)//如果AC题数不同
  return a.num > b.num;
 if (a.time != b.time)
  return a.time < b.time;
 return strcmp(a.name, b.name) < 0;
}
int main()
{
 int n,m,res,i,a1,a2;
 char mark[15];
 scanf("%d %d", &n, &m);
 for (i = 0; scanf("%10s", s[i].name)!=EOF; i++)
 {
  s[i].num = 0; s[i].time = 0;
  for (int j = 0; j < n; j++)
  {
   //scanf("%s", mark);
   res = scanf("%d(%d)", &a1, &a2);//sscanf()函数--读取格式化字符串,返回成功赋值的个数
   if (res == 2)//如果读取到两个数
   {
    s[i].num++;
    s[i].time+= a1 + a2 * m;
   }
   else if (res == 1 && a1 > 0)//如果读取到一个数,且是正数
   {
    s[i].num++;
    s[i].time += a1;
   }
  }
 }
 sort(s, s + i, comp);//结构体排序
 for (int j = 0; j < i; j++)//输出结果
 {
  printf("%-10s %2d %4d\n", s[j].name, s[j].num, s[j].time);
 }
}

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

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

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|
±–±--±–±--±–±--±–±--±–±--±–±--±–+

解题思路

读入数据,采用结构体存储每次读入牌的花色和牌面值,分别用char a和char b表示,为了方便比较将所有的字符转换成整型比较,为了保证输出,将牌按照South,West,North,East存储。

代码

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

struct poke
{
	char a;//花色 
	char b;//牌面值 
	int c;//转化成整型的花色 
	int d;//转化成整型的牌面值 
	bool operator<(const poke& p) const
	{
		if (c != p.c) return c < p.c;
		if (d != p.d) return d < p.d;
		else return false;
	}
}card[4][13];


int swi1(poke m)
{
	switch (m.a)
	{
	case 'H':
		return 4;
		break;
	case 'S':
		return 3;
		break;
	case 'D':
		return 2;
		break;
	case 'C':
		return 1;
		break;
	}
}

int swi2(poke m)
{
	switch (m.b)
	{
	case 'T':
		return 10;
		break;
	case 'J':
		return 11;
		break;
	case 'Q':
		return 12;
		break;
	case 'K':
		return 13;
		break;
	case 'A':
		return 14;
		break;
	}
}

int main()
{
	char m = 0;
	int first = 0;
	while (scanf("%c",&m) != '#')
	{
		if (m == 'E') first = 0;
		else if (m == 'S') first = 1;
		else if (m == 'W') first = 2;
		else first = 3;
		//cout << first << endl;
		for (int i = 0; i < 13; i++)
			for (int j = 0; j < 4; j++)
			{
				cin >> card[(j + first) % 4][i].a >> card[(j + first) % 4][i].b;
				card[(j + first) % 4][i].c = swi1(card[(j + first) % 4][i]);
				card[(j + first) % 4][i].d = swi2(card[(j + first) % 4][i]);
			}

		for (int i = 0; i < 4; i++)
			sort(card[i], card[i] + 13);

		for (int i = 0; i < 4; i++)
		{
			if (i == 0) printf("South ");
			else if (i == 1) printf("West ");
			else if (i == 2) printf("North ");
			else printf("East ");

			printf("player:\n");

			for (int k = 0; k < 13; k++)
				printf("+---");
			printf("+\n");

			for (int k = 0; k < 13; k++)
			{
				printf("|%c %c", card[i][k].b, card[i][k].b);
			}
			printf("|\n");

			for (int k = 0; k < 13; k++)
			{
				printf("| %c ", card[i][k].a, card[i][k].a);
			}
			printf("|\n");

			for (int k = 0; k < 13; k++)
			{
				printf("|%c %c", card[i][k].b, card[i][k].b);
			}
			printf("|\n");

			for (int k = 0; k < 13; k++)
				printf("+---");
			printf("+\n");
		}
	}
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值