实验A、B、C三个题目

题目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
是同一种,本质上就是一条链,编号其实是没有关系的

输入

输入第一行为数据的组数T(1≤T≤200000)。每组数据有5行,每行是两个整数a, b(1≤a,b≤6,a ≤b)

数据保证,输入的烷烃基是以上5种之一

输出

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

问题理解

我们来仔细的分析图片,你会发现这五个烷烃其实就是以前所学习的同分异构体。顶点的个数都是一样的,只是构造不一样。这个时候就需要从构造上来区分他们的不同。
1.首先我建立了一个结构体chemical_bond,用来存放它的入度以及和它相连接的顶点的名称。
2.然后我建立了一个类alkyl,用来专门对输入的烷烃处理,包含初始化、建立连接和输出。其中jisuan这个变量用来储存整个烷烃中顶点的最大的度的情况(这里我做了一些改变,导致意义差不多,但其值却不是最大的度,主要流程就是每次遇见度为3,4的点就使jisuan的值增加1,2)。thealkyl是以结构体chemical_bond为基础的线性表,用来储存每个节点的链接情况。
3.每一次输入两个顶点,就采用connected函数将其输入进类的线性表中。并对那两个顶点的度进行计算。它们所链接的点也加入其结构体里的shu[]中;
4.判断是什么烷烃时,首先检查我们之前处理的jisuan的值。由图可知分别是:0,1,1,2,3;依靠这个举动可以判断出其中的三类情况。剩下两个最大入度为3的,我采用遍历其顶点,找到最大入度的顶点,再观察它的所邻着的点的入度。三个邻点有两个是入度为2的是3-methylpentane,剩下的就是2-methylpentane。即可完成判断。

代码样例


#include<iostream>
#include<cmath>
//#include<queue>
//n-hexane,2-methylpentane,3-methylpentane,2,3-dimethlbutane,2,2-dimethylbutane;
using namespace std;

struct chemical_bond
{
	int du;
	int shu[6];
} ;
template<class T>
class alkyl
{
 	public:
 		alkyl()
		{
			thealkyl=new struct chemical_bond [7];
			jisuan=0;
 			for(int i=1;i<=6;i++)
 			{
 				thealkyl[i].du=0;
			}
		}
		void clear()//初始化
		{
			jisuan=0;
		 	for(int i=1;i<=6;i++)
 			{
 				thealkyl[i].du=0;
			}
		}
		void connected(int a,int b);
		void output();
		 
	private:
		struct chemical_bond *thealkyl;
		int jisuan;
};
template<class T>
void alkyl<T>::connected(int a,int b)
{
	thealkyl[a].shu[thealkyl[a].du]=b;
	thealkyl[b].shu[thealkyl[b].du]=a;
	thealkyl[a].du++;
	thealkyl[b].du++;
	if(thealkyl[a].du>3)
		jisuan=jisuan+2;
	else if(thealkyl[a].du>2)
		jisuan++;
	if(thealkyl[b].du>3)
		jisuan=jisuan+2;
	else if(thealkyl[b].du>2)
		jisuan++;
}
template<class T>
void alkyl<T>::output()
{
	if(jisuan==3)
	{
		//cout<<jisuan<<endl;
		cout<<"2,2-dimethylbutane"<<endl;
		jisuan=0;
		return;
	}
	if(jisuan==2)
	{
	//	cout<<jisuan<<endl;
		cout<<"2,3-dimethylbutane"<<endl;
		jisuan=0;
		return;
	}
	if(jisuan==0)
	{
		//cout<<jisuan<<endl;
		cout<<"n-hexane"<<endl;
		jisuan=0;
		return;
	}
	if(jisuan==1)
	{
	//	cout<<jisuan<<endl;
		int i;
		for(i=0;i<6;i++)
		{
			if(thealkyl[i].du==3)
				break;
		}
		int num=0;
		for(int j=0;j<thealkyl[i].du;j++)
		{
			if(thealkyl[thealkyl[i].shu[j]].du==2)
				num++;
		}
		if(num==2)
			cout<<"3-methylpentane"<<endl;
		else
			cout<<"2-methylpentane"<<endl;
			
			jisuan=0;
	}
	else
		cout<<"计算wrong   jisuan="<<jisuan<<endl;
	return; 
}
int main()
{	
	int N;
	
	int a,b;
	cin>>N;
	alkyl<int> g;
	for(int i=0;i<N;i++)
	{
		g.clear();
		for(int j=0;j<5;j++)
		{
			cin>>a>>b;
			g.connected(a,b);
		}
		g.output();
	}
	
	
}

遇到的问题

代码有些累赘,对于stl的使用不多,并且在调试的过程中废了很多功夫,就是因为那些循环的变量没有处理到位

题目B——HDU2093排序

题目描述

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

输入

输入数据包含多行,第一行是共有的题数n(1≤n≤12)以及单位罚时m(10≤m≤20),之后的每行数据描述一个学生的信息,首先是学生的用户名(不多于10个字符的字串)其次是所有n道题的得分现状,其描述采用问题描述中的数量标记的格式,见上面的表格。

输出

根据这些学生的得分现状,输出一个实时排名。实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。

问题理解

1.首先定义了一个结构体 person,包含参赛者的姓名char、对的题数int、用时int。
2.再建立一个线性表person_grade[],用以储存所有的参赛者的情况
3.输入时,直接输入参赛者姓名,再输入一个数字。根据和这个数字的大小来判断是否会有字符在里面。因为输入的格式只有,正数、正数(正整数),负数,零这几个情况。于是只要输入的数大于零,就判断是否会时‘正数(正整数)’的情况。
并在输入的时候,对每次的时间并加上其罚时直接处理好。
4.比较,采用了sort函数,头文件algorithm。用法sort(first_pointer,first_pointer+n,cmp);其中cmp是自己定义的bool函数,用来比较大小。(为了便于理解,即bool compared(a,b)中,a是前一个元素,b是后一个元素。整个sort函数就是改变排序,使得其compared(a,b)回值为真的的排列情况即可。这个方法大大减少了我码代码要求。
5.输出,这个输出是看网上的代码。%-10s 其意思就是把name的字符串从0到9全部输出,%2d和%4d就是输出几位的整数。

代码

#include <iostream>
#include <algorithm>
using namespace std;
 
struct person
{
	char name[10];
	int number;
	int time;
};
bool compare(person& a,person& b)
{
	if(a.number!=b.number)
	{
		return a.number>b.number;
	}
	else
	{
		if(a.time!=b.time)
		{
			return a.time<b.time;
		}
		else
		{
			return a.name> b.name;
		}
	}
}
int main()
{
	int i=0;
	int n,m;
	cin>>n>>m;
	int shu,a;
	struct person person_grade[10000];
	
	while(cin>>person_grade[i].name)
	{
		person_grade[i].number=0;
		person_grade[i].time=0;
		for(int j=0;j<n;j++)
		{
			cin>>shu;
			if(shu>0)
			{
				person_grade[i].number++;
				person_grade[i].time=person_grade[i].time+shu;
				if(getchar()=='(')
				{
					cin>>a;
					person_grade[i].time=person_grade[i].time+a*m;
					getchar();//吸收另一个括号 
				}
			}
			
		}
		i++;
	}

	sort(person_grade,person_grade+i,compare);
	int k;
	for(k=0;k<i;k++){
		printf("%-10s %2d %4d\n",person_grade[k].name,person_grade[k].number,person_grade[k].time);
	}
}

问题

对于stl不太熟,是看了网上的代码改编的,不过,这样也让我了解了这个用法,不错。

问题C——POJ1786

问题描述

牌局由四个人构成,围成一圈。我们称四个方向为北 东 南 西。对应的英文是North,East,South,West。游戏一共由一副扑克,也就是52张构成。开始,我们指定一位发牌员(东南西北中的一个,用英文首字母标识)开始发牌,发牌顺序为顺时针,发牌员第一个不发自己,而是发他的下一个人(顺时针的下一个人)。这样,每个人都会拿到13张牌。
现在我们定义牌的顺序,首先,花色是(梅花)<(方片)<(黑桃)<(红桃),(输入时,我们用C,D,S,H分别表示梅花,方片,黑桃,红桃,即其单词首字母)。对于牌面的值,我们规定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。
现在你作为上帝,你要从小到大排序每个人手中的牌,并按照给定格式输出。(具体格式见输出描述和样例输出)。

输入

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

输出

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

问题分析

1.建立了一个结构体card,包含其牌面number,牌的花色color。
2.采用二维线性表playing_card来存放输入的发牌顺序,其中先对哪一个玩家发牌做一个处理。我直接是一个个比较一开始输入的字符。并对k进行赋值。这样在输入的循环里就可以从k到k+n进行来回对二维线性表输入。
3.排序时,我采用了sort函数和map函数。对每一个玩家手上的牌用sort函数进行排序。为了方便排序,建立了一个map color_compared。并在主函数里对每个花色赋予对应的优先值。(按照其比较的顺序来)
4.对应着输出即可

代码


#include<iostream>
using namespace std;
#include<algorithm>
#include<map> 
struct card
{
	char number;
	char color;
};
//2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。 ;;;
//C,D,S,H
//S,W,N,E
map<char,int> color_compared;
bool compared(card& a,card& b)
{
	if(a.color!=b.color)
	{
		return color_compared[a.color]<color_compared[b.color];
	}
	else
	{
	
		return color_compared[a.number]<color_compared[b.number];
	}
	
}
int main()
{
	color_compared['2']=1;
	color_compared['3']=2;
	color_compared['4']=3;
	color_compared['5']=4;
	color_compared['6']=5;
	color_compared['7']=6;
	color_compared['8']=7;
	color_compared['9']=8;
	color_compared['T']=9;
	color_compared['J']=10;
	color_compared['Q']=11;
	color_compared['K']=12;
	color_compared['A']=13;
	
	color_compared['C']=1;
	color_compared['D']=2;
	color_compared['S']=3;
	color_compared['H']=4;
	char player;
	scanf("%c",&player); 
	while(player!='#')
	{
		struct card playing_card[4][13];
		int  k;
		if(player=='S')
			k=1;
		if(player=='W')
			k=2;
		if(player=='N')
			k=3;
		if(player=='E')
			k=0;
	//cout<<k<<" "<<player<<endl;
		getchar();
		for(int i=0;i<13;i++)
		{
		
			for(int j=k;j<k+4;j++)
			{
				if(i==6&&j==k+2)
					getchar();
				scanf("%c",&playing_card[j%4][i].color);
				scanf("%c",&playing_card[j%4][i].number);
			//cout<< playing_card[j%4][i].color<<"   "<<playing_card[j%4][i].number<<endl;
			}
		}
		sort(playing_card[0],playing_card[0]+13,compared);
		sort(playing_card[1],playing_card[1]+13,compared);
		sort(playing_card[2],playing_card[2]+13,compared);
		sort(playing_card[3],playing_card[3]+13,compared);
		for(int i=0;i<4;i++)
		{
			if(i==0)
				cout<<"South player:"<<endl;
			if(i==1)
				cout<<"West player:"<<endl;
			if(i==2)
				cout<<"North player:"<<endl;
			if(i==3)
				cout<<"East player:"<<endl;
		
			cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
			cout<<"|";
			for(int j=0;j<13;j++)
			{
				cout<<playing_card[i][j].number<<" "<<playing_card[i][j].number<<"|";
			}
			cout<<endl;
			cout<<"|";
			for(int j=0;j<13;j++)
			{
				cout<<" "<<playing_card[i][j].color<<" "<<"|";
			}
			cout<<endl;
			cout<<"|";
			for(int j=0;j<13;j++)
			{
				cout<<playing_card[i][j].number<<" "<<playing_card[i][j].number<<"|";
			}
			cout<<endl;
			cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;	
		}
		cout<<endl;
		getchar();
		scanf("%c",&player); 
	}
	
	
}

遇到的问题

1.输入时莫名其妙对的不准,我做了调试之后发现,是输入时里面有回车,但是把它当作一个字符读进去了,导致后面的对不上,全部错位。于是在里面加了两个getchar来吸收回车。
2.读题时,没读准,理所应当的按照自己的习惯排了序,结果出来,才发现要求是先花色再大小。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值