2005年浙江大学计算机及软件工程研究生机试真题

题目1010:A + B

题目描述:
读入两个小于100的正整数A和B,计算A+B.
需要注意的是:A和B的每一位数字由对应的英文单词给出.
输入:
测试输入包含若干测试用例,每个测试用例占一行,格式为"A + B =",相邻两字符串有一个空格间隔.当A和B同时为0时输入结束,相应的结果不要输出.
输出:
对每个测试用例输出1行,即A+B的值.
样例输入:
one + two =
three four + five six =
zero seven + eight nine =
zero + zero =
样例输出:
3
90
96
    <pre name="code" class="cpp">    #include<iostream>
    #include<string>
    using namespace std;
    int trans(string a)
    {
            string digital_name[]={"zero","one","two","three","four","five","six","seven","eight","nine"};
            for(int i=0;i<10;i++)
            {
                    if(a==digital_name[i])
                    {
                            return i;
                    }
            }
    }

    int main()
    {
            int a,b;
            string buffer;
            do{
                    a=0;
                    b=0;
            while(cin>>buffer&&buffer!="+")//字符串以空格作为输出结束符号 
                    a=a*10+trans(buffer);
            while(cin>>buffer&&buffer!="=")
                    b=b*10+trans(buffer);
            if(a+b!=0)
            	cout<<a+b<<endl;
                   
            }while(a+b!=0);//用和不为0代替zero+zero 
            return 0;
    }


 

题目1011:最大连续子序列

题目描述:
    给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和为20。现在增加一个要求,即还需要输出该子序列的第一个和最后一个元素。
输入:

    测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( K< 10000 ),第2行给出K个整数,中间用空格分隔。当K为0时,输入结束,该用例不被处理。

输出:

    对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。

样例输入:
6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 3 2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0
样例输出:
20 11 13
10 1 4
10 3 5
10 10 10
0 -1 -2
0 0 0
//动态规划思想
#include<iostream>
using namespace std;
int main()
{
	int k,a[10006];
	while(cin>>k&&k)
	{
		int sum=0,b,begin,end,flag=0,start;
		for(int i=0;i<k;i++)
		{
			cin>>a[i];
			if(a[i]>=0)
				flag=1;
		}
		if(flag==0)
			cout<<"0"<<" "<<a[0]<<" "<<a[k-1]<<endl;
		for(int i=0;i<k;i++)
		{
			b=0;
			for(int j=i;j<k;j++)
			{
				b+=a[j];
				start=j;
				if(b>sum)
				{
					sum=b;
					end=start;//终止元素位置 
					begin=i;//起始元素位置 
				}
				
			}
			
		}
		cout<<sum<<" "<<a[begin]<<" "<<a[end]<<endl;		
	}
	return 0;
}




题目1012:畅通工程

题目描述:

    某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?

输入:

    测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。
    注意:两个城市之间可以有多条道路相通,也就是说
    3 3
    1 2
    1 2
    2 1
    这种输入也是合法的
    当N为0时,输入结束,该用例不被处理。

输出:

    对每个测试用例,在1行里输出最少还需要建设的道路数目。

样例输入:
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0
样例输出:
1
0
2
998
算法思想:利用并查集求解图的分支个数,需要修建的道路个数就是分支数-1

#include<iostream>
#include<string.h>
using namespace std;
int pre[1050];
int t[1050];               //t 用于标记独立块的根结点    
int find(int x)//找到x的上级 
{
	int r=x;
	while(pre[r]!=r)//如果r的上级不是r,即r不是根节点 
	 r=pre[r];//r是根节点
	/路径压缩,将所有下属的上级都设置为根节点 
	int i=x,j;
	while(pre[i]!=r)
	{
		j=pre[i];//记录i的上级 
		pre[i]=r;//将r的上级设置为根节点 
		i=j;//对上级继续处理 
	 } 
	/ 
	 return r;//返回根节点 
}
void join(int x,int y)//判断x和y的上级是否相同,不同则合并为同一个上级 
{
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy)//上级不一样 
	{
		pre[fy]=fx;//将fx设置为fy的上级,使得二者上级一样 
	}
 } 
int main()
{
	int n,m,a,b,ans;
	while(cin>>n>>m&&n) 
	{
		for(int i=1;i<=n;i++)
			pre[i]=i;//将每个城市设置为独立的个体,每个城市的上技是他自己 
		while(m--)
		{
			cin>>a>>b;//输入两个城市
			join(a,b);//将两个城市合并为一个分支 
		} 
		memset(t,0,sizeof(t)) ;
		for(int i=1;i<=n;i++)
		{
			t[find(i)]=1;//将独立的根节点设置为1,有几个1就是有几个独立的根节点 
		}
		ans=0;
		for(int i=1;i<=n;i++)
		{
			if(t[i])
				ans++;//有几个独立的城市块 
		} 
		cout<<ans-1<<endl; //需要连线的是独立城市块数-1 
	}
	return 0;
}




题目1013:开门人和关门人

题目描述:
  每天第一个到机房的人要把门打开,最后一个离开的人要把门关好。现有一堆杂乱的机房签到、签离记录,请根据记录找出当天开门和关门的人。
输入:
测试输入的第一行给出记录的总天数N ( N> 0 ),下面列出了N天的记录。 每天的记录在第一行给出记录的条目数M (M > 0 ),下面是M行,每行的格式为 证件号码 签到时间 签离时间 。时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15的字符串。
输出:
对每一天的记录输出1行,即当天开门和关门人的证件号码,中间用1空格分隔。 注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,且没有多人同时签到或者签离的情况。
样例输入:
3
1

ME3021112225321 00:00:00 23:59:59

2

EE301218 08:05:35 20:56:35
MA301134 12:35:45 21:40:42
3

CS301111 15:30:28 17:00:10

SC3021234 08:00:00 11:25:25

CS301133 21:45:00 21:58:40

样例输出:

ME3021112225321 ME3021112225321

EE301218 MA301134
SC3021234 CS301133

<pre name="code" class="cpp">#include<iostream>
#include<algorithm>
using namespace std;
struct record{
	char num[100];
	char begin[100];
	char end[100];
}a[100];
int cmp1(struct record a,struct record b)
{
	int num1,num2;
	num1=((a.begin[0]-'0')*10+a.begin[1]-'0')*3600+((a.begin[3]-'0')*10+a.begin[4]-'0')*60+((a.begin[6]-'0')*10+a.begin[7]-'0');
	num2=((b.begin[0]-'0')*10+b.begin[1]-'0')*3600+((b.begin[3]-'0')*10+b.begin[4]-'0')*60+((b.begin[6]-'0')*10+b.begin[7]-'0');
	return num1<num2?1:0;
}
int cmp2(struct record a,struct record b)
{
	int num1,num2;
	num1=((a.end[0]-'0')*10+a.end[1]-'0')*3600+((a.end[3]-'0')*10+a.end[4]-'0')*60+((a.end[6]-'0')*10+a.end[7]-'0');
	num2=((b.end[0]-'0')*10+b.end[1]-'0')*3600+((b.end[3]-'0')*10+b.end[4]-'0')*60+((b.end[6]-'0')*10+b.end[7]-'0');
	return num1>num2?1:0;
}
int main()
{
	int n,m;
	cin>>n;
	while(cin>>m)
	{
		for(int i=0;i<m;i++)
			cin>>a[i].num>>a[i].begin>>a[i].end;
		sort(a,a+m,cmp1);
		cout<<a[0].num<<" ";
		sort(a,a+m,cmp2);
		cout<<a[0].num<<endl;
	}
	return 0;
}


 
 

题目1014:排名

题目描述:
    今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的考生,并将他们的成绩按降序打印。
输入:

    测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N < 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号(题目号由1到M)。
    当读入的考生人数为0时,输入结束,该场考试不予处理。

输出:

    对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考号的升序输出。

样例输入:
4 5 25
10 10 12 13 15
CS004 3 5 1 3
CS003 5 2 4 1 3 5
CS002 2 1 2
CS001 3 2 3 5
1 2 40
10 30
CS001 1 2
2 3 20
10 10 10
CS000000000000000001 0
CS000000000000000002 2 1 2
0
样例输出:
3
CS003 60
CS001 37
CS004 37
0
1
CS000000000000000002 20
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
struct stu{
	char num[100];
	int total;
	int solve[100];
	int grade;
}a[10000];
int cmp(struct stu a,struct stu b)
{
	int num1=0,num2=0;
	for(int i=0;i<strlen(a.num);i++)
	{
		if(a.num[i]<='9'&&a.num[i]>='0')
			num1=num1*10+a.num[i]-'0';
	}
	for(int i=0;i<strlen(b.num);i++)
	{
		if(b.num[i]<='9'&&b.num[i]>='0')
			num2=num2*10+b.num[i]-'0';
	}
	if(a.grade==b.grade)
		return num1<num2;
	return a.grade>b.grade ;
}
int main()
{
	int n,m,g,score[100],sum;
	while(cin>>n&&n)
	{
		cin>>m;
		cin>>g;
		sum=0;
		for(int i=1;i<=m;i++)
			cin>>score[i];
		for(int i=0;i<n;i++)
		{
			cin>>a[i].num>>a[i].total;
			for(int j=1;j<=a[i].total;j++)
				cin>>a[i].solve[j];
			a[i].grade=0;
		}
		for(int i=0;i<n;i++)
		{
			for(int j=1;j<=a[i].total;j++)
				a[i].grade+=score[a[i].solve[j]];
			if(a[i].grade>=g)
				sum++;
		}
		cout<<sum<<endl;
		sort(a,a+n,cmp);
		for(int i=0;i<sum;i++)
			cout<<a[i].num<<" "<<a[i].grade<<endl;
	}	
    return 0;
}







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值