程序设计基础与实践 Week2 实验(烷烃基、成绩测评、扑克牌)

**

A-化学

**
题目

化学很神奇,以下是烷烃基。
在这里插入图片描述

假设如上图,这个烷烃基有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-methylpentane:存在一个三度顶点,且该顶点与两个一度顶点和一个二度顶点相邻。
3-methylpentane :存在一个三度顶点,且该顶点与一个一度顶点和两个二度顶点相邻。
2,3-dimethylbutane:存在两个三度顶点。
2,2-dimethylbutane:存在一个四度顶点。
C++代码

#include<iostream>
using namespace std;
int main()
{
 long long t=0;
 cin>>t;
 for(long long i=0;i<t;i++)
 {
  int a[7][7];//定义二维数组,记录各点之间的相邻情况 
  int *label=new int[7];//定义标记数组,记录各点的度数 
  for(int j=0;j<7;j++)//赋初值 
  {
   label[j]=0;
   for(int k=0;k<7;k++)
   {
    a[j][k]=0;
   }
  }
  int x=0,y=0;
  for(int j=0;j<5;j++)//输入样例
  {
   cin>>x>>y;
   a[x][y]++;
   a[y][x]++;
   label[x]++;
   label[y]++;
  }
  int c1=0,c3=0,c4=0;//分别记录一度、三度、四度顶点个数 
  int point=0;//记录三度顶点的编号 
  for(int j=1;j<7;j++)
  {
   if(label[j]==1) c1++;
   else if(label[j]==3) 
   {
    c3++;
    point=j;
   }
   else if(label[j]==4) c4++;
  }
  if(c1==2) cout<<"n-hexane"<<endl;
  else if(c3==1)
  {
   int sum=0;
   for(int j=0;j<7;j++)
   {
    if(a[point][j]==1&&label[j]==1)//记录三度顶点相邻一度顶点个数 
    {
     sum++;
    }
   }
   if(sum==2) cout<<"2-methylpentane"<<endl;
   else if(sum==1) cout<<"3-methylpentane"<<endl;
  }
  else if(c3==2) cout<<"2,3-dimethylbutane"<<endl;
  else if(c4==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

解题思路
先定义student结构体记录学生姓名、得分以及耗时,并重载小于号。定义结构体数组存放输入数据,其中根据输入数据中是否带符号或括号分情况计算分数及耗时。将数组排序输出。
C++代码

#include<iostream>
#include <iomanip>
#include<string>
using namespace std;
struct student
{
 string name;
 int score,time; 
 bool operator<(const student stu)//重载< 
 {
  if(score!=stu.score) 
  {
   return score>stu.score;
  }
  else if(time!=stu.time)
  {
   return time<stu.time;
  }
  else
  {
   return name<stu.name;
  }
 } 
};
int main()
{
 int n=0,m=0;
 cin>>n>>m;
 string name;
 student *s=new student[10000];
 int k=0;
 while(cin>>name)//赋值 计算 
 {
  s[k].name=name;
  int score=n,sum=0;
  for(int i=0;i<n;i++)
  {
   int time=0;
   string data;
   cin>>data;
   if(data[0]=='-'||data=="0")//带负号或为0,不计入时间 
   {
    score--;
    } 
   else //计算时间 
   {
    int j;
    for(j=0;j<data.length();j++)
    {
     if(data[j]=='(') break;
     else//计算实际花费时间 
     {
      int t=data[j]-48;
      time=time*10+t; 
     }
    }
    j++;
    int x=0;
    for(;j<data.length();j++)
    {
     if(data[j]==')') break;
     else//计算罚时 
     {
      int t=data[j]-48;
      x=x*10+t;
     }
    }
    time=time+x*m; 
   }
   sum=sum+time;//计算学生花费总时间 
  }
  s[k].score=score;
  s[k].time=sum;
  k++;
 }
 for (int i = k; i > 1; i--)//根据规则排序 
 {  
  for (int j= 0; j< i- 1; j++)
  {
   if (s[j+1]<s[j])
   {
    student change;
    change.name=s[j].name,change.score=s[j].score,change.time=s[j].time;
    s[j].name=s[j+1].name,s[j].score=s[j+1].score,s[j].time=s[j+1].time;
    s[j+1].name=change.name,s[j+1].score=change.score,s[j+1].time=change.time;
   }
  }
 } 
 for(int i=0;i<k;i++)//输出排序结果 
 {
     cout<<std::left<< setw(10)<< s[i].name << " ";
     cout<<setw(2)<<setiosflags(ios::right)<<s[i].score<<" ";
  cout<<setw(4)<<setiosflags(ios::right)<<s[i].time<<endl;
 }
 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|
+---+---+---+---+---+---+---+---+---+---+---+---+---+

解题思路
利用map将扑克牌的花色、数值以及输入的方向对应到整型数据上。定义card结构体存放每张牌的花色、数值以及发牌顺序,并根据题目要求重载小于号。定义一个结构体类型的二维数组,数组第一行到第四行分别存放S、W、N、E相应方向的发牌情况。根据输入的方向,从对应方向的下一行(根据(方向对应的整型数据+1)%4判断对应行)循环一行行输入数据。最后将二维数据的每行数据进行排序输出。
C++代码

#include<iostream>
#include<map>
using namespace std;
map<char,int> m;
map<char,int> d;
struct card
{
 char suit,value;
 int id;
 bool operator<(const card c)
 {
  if(suit!=c.suit) 
  {
   return m[suit]<m[c.suit];
  }
  else if(value!=c.value)
  {
   return m[value]<m[c.value];
  }
  else
  {
   return id<c.id;
  }
 }
};
int main()
{
 m['2']=2,m['3']=3,m['4']=4,m['5']=5,m['6']=6,m['7']=7;//扑克牌花色和数值 
 m['8']=8,m['9']=9,m['T']=10,m['J']=11,m['Q']=12,m['K']=13;
 m['A']=14,m['C']=15,m['D']=16,m['S']=17,m['H']=18;
 d['S']=0,d['W']=1,d['N']=2,d['E']=3;//方向 
 char direction;
 while(true)
 {
  card ca[4][13];
  cin>>direction;
  if(direction=='#') return 0;
  int dir=(d[direction]+1)%4;
  string str1,str2;
  cin>>str1>>str2;
  int k=0,label=-1;
  for(int i=0;i<26;i++)
  {
   if(k%8==0) label++;//每输入四个扑克牌的数据,数组向后一列 
   ca[dir][label].suit=str1[k];
   k++;
   ca[dir][label].value=str1[k];
   k++;
   ca[dir][label].id=i;
   dir=(dir+1)%4;
  }
  for(int i=0;i<26;i++)
  {
   if(k%8==0) label++;
   ca[dir][label].suit=str2[k-52];
   k++;
   ca[dir][label].value=str2[k-52];
   k++;
   ca[dir][label].id=i+26;
   dir=(dir+1)%4; 
  }
  for(k=0;k<4;k++)
  {
   for (int i =13; i>1; i--)//当没有过交换过程时跳出循环 
   { 
    for (int j=0; j<i-1; j++)
    {
     if (ca[k][j+1]<ca[k][j])
     {
      card change;
      change.suit=ca[k][j].suit,change.value=ca[k][j].value,change.id=ca[k][j].id;
      ca[k][j].suit=ca[k][j+1].suit,ca[k][j].value=ca[k][j+1].value,ca[k][j].id=ca[k][j+1].id;
      ca[k][j+1].suit=change.suit,ca[k][j+1].value=change.value,ca[k][j+1].id=change.id;
     }
    }
   }
  }
  for(int j=0;j<4;j++)
  {
   switch(j)
   {
    case 0:
     cout<<"South player:"<<endl;
     break;
    case 1:
     cout<<"West player:"<<endl;
     break;
    case 2:
     cout<<"North player:"<<endl;
     break;
    case 3:
     cout<<"East player:"<<endl;
     break; 
   }
   for(int i=0;i<13;i++)
   {
    if(i==12) cout<<"+---+"<<endl;
    else cout<<"+---";
   }
   for(int i=0;i<13;i++)
   {
    if(i==12) cout<<"|"<<ca[j][i].value<<" "<<ca[j][i].value<<"|"<<endl;
    else cout<<"|"<<ca[j][i].value<<" "<<ca[j][i].value;
   }
   for(int i=0;i<13;i++)
   {
    if(i==12) cout<<"|"<<" "<<ca[j][i].suit<<" |"<<endl;
    else cout<<"|"<<" "<<ca[j][i].suit<<" ";
   }
   for(int i=0;i<13;i++)
   {
    if(i==12) cout<<"|"<<ca[j][i].value<<" "<<ca[j][i].value<<"|"<<endl;
    else cout<<"|"<<ca[j][i].value<<" "<<ca[j][i].value;
   }
   for(int i=0;i<13;i++)
   {
    if(i==12) cout<<"+---+"<<endl;
    else cout<<"+---";
   }
  }
  cout<<endl;
 }
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值