杭电历年复试题目——2017年

申明:写本篇文章的目的是为了方便自己使用,以下代码纯属自己编写,因为没有评测系统,因此无法保证正确性,若有人看到错误,请指正,谢谢。

题目1:关羽过关斩三将,输入四个人的武力值(大于0小于50),若超过界限需要重新输入,关羽的武力值x,将士武力值为y,满足(x-y)^2+(x-y)+41 若为素数则关羽获胜,若关羽三次获胜输出WIN,若失败则输出失败的将领序号(第几关)。

#include<stdio.h>
#include<math.h>
bool isprime(int x)
{
	if(x==1)
		return false;
	for(int i=2;i<=sqrt(x);i++)
		if(x%i==0)
			return false;
	return true;
}
int main()
{
	int y[4],temp;
	int win=0;
	for(int i=0;i<4;i++)
	{
		scanf("%d",&temp);
		if(0<temp&&temp<50)
			y[i]=temp;
		else 
		{
			printf("武力值应该在0到50之间,请重新输入\n");
			i--;
		}
	}
	for(int i=1;i<4;i++)
	{
		temp=(y[0]-y[i])*(y[0]-y[i])+(y[0]-y[i])+41;
		if(isprime(temp))
			win++;
		else printf("%d\n",i);
	}
	if(win==3)
		printf("WIN\n");
}

题目2:
输入N个员工,每个员工输出ID号,上班时间,下班时间,
第一行输出 最早去的员工的ID和上班时间
第二行输出 最迟走的员工的ID和下班时间
第三行输出 工作最久的员工的ID和上班时间<按照数据来讲,按理来说应该是上班时间最久的>
(数据瞎编的)
sampleinput:
ID100001, 07:00:00 17:00:00
ID100002, 08:00:00 18:00:00
ID100003, 09:00:00 21:00:00
sampleout:
OPEN:ID100001, 07:00:00
CLOSE:ID100003, 21:00:00
STAR:ID100003, 12:00:00

#include<stdio.h>
#include<algorithm>
using namespace std;
struct people
{
	char ID[10];
	int from_h,from_m,from_s;
	int to_h,to_m,to_s;
	int sum;
}p[1001];
bool cmp_open(people x,people y)
{
	if(x.from_h!=y.from_h)
		return x.from_h<y.from_h;
	else if(x.from_m!=y.from_m)
		return x.from_m<y.from_m;
	else return x.from_s<y.from_s;
}
bool cmp_close(people x,people y)
{
	if(x.to_h!=y.to_h)
		return x.to_h>y.to_h;
	else if(x.to_m!=y.to_m)
		return x.to_m>y.to_m;
	else return x.to_s>y.to_s;
}
bool cmp_star(people x,people y)
{
	return x.sum>y.sum;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%s",p[i].ID);
		getchar();
		scanf("%d:%d:%d",&p[i].from_h,&p[i].from_m,&p[i].from_s);
		scanf("%d:%d:%d",&p[i].to_h,&p[i].to_m,&p[i].to_s);
		int temp_f,temp_t;
		temp_f=p[i].from_h*3600+p[i].from_m*60+p[i].from_s;
		temp_t=p[i].to_h*3600+p[i].to_m*60+p[i].to_s;
		p[i].sum=temp_t-temp_f;
	}
	sort(p,p+n,cmp_open);
	printf("OPEN:%s %02d:%02d:%02d\n",p[0].ID,p[0].from_h,p[0].from_m,p[0].from_s);
	sort(p,p+n,cmp_close);
	printf("CLOSE:%s %02d:%02d:%02d\n",p[0].ID,p[0].to_h,p[0].to_m,p[0].to_s);
	sort(p,p+n,cmp_star);
	int mm,hh,ss,tag;
	if(p[0].to_s<p[0].from_s)
	{
		ss=60+(p[0].to_s-p[0].from_s);
		tag=1;
	}
	else
	{
		ss=p[0].to_s-p[0].from_s;
		tag=0;
	}
	if(p[0].to_m<p[0].from_m+tag)
	{
		mm=60+(p[0].to_m-p[0].from_m-tag);
		tag=1;
	}
	else
	{
		mm=p[0].to_m-p[0].from_m-tag;
		tag=0;
	}
	if(p[0].to_h<p[0].from_h+tag)
	{
		hh=60+(p[0].to_h-p[0].from_h-tag);
		tag=1;
	}
	else
	{
		hh=p[0].to_h-p[0].from_h-tag;
		tag=0;
	}
	printf("STAR:%s %02d:%02d:%02d\n",p[0].ID,hh,mm,ss);
}

考虑到如果有多组数据输出的情况(即最早到的人有多个,最迟到的人有多个,上班时间最长的人有多个),代码修改如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
struct people
{
	char ID[10];
	int from_h,from_m,from_s;
	int to_h,to_m,to_s;
	int sum;
}p[1001];
bool cmp_open(people x,people y)
{
	if(x.from_h!=y.from_h)
		return x.from_h<y.from_h;
	else if(x.from_m!=y.from_m)
		return x.from_m<y.from_m;
	else return x.from_s<y.from_s;
}
bool cmp_close(people x,people y)
{
	if(x.to_h!=y.to_h)
		return x.to_h>y.to_h;
	else if(x.to_m!=y.to_m)
		return x.to_m>y.to_m;
	else return x.to_s>y.to_s;
}
bool cmp_star(people x,people y)
{
	return x.sum>y.sum;
}
int main()
{
	int n;
	int mm,hh,ss,tag,temp;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%s",p[i].ID);
		getchar();
		scanf("%d:%d:%d",&p[i].from_h,&p[i].from_m,&p[i].from_s);
		scanf("%d:%d:%d",&p[i].to_h,&p[i].to_m,&p[i].to_s);
		int temp_f,temp_t;
		temp_f=p[i].from_h*3600+p[i].from_m*60+p[i].from_s;
		temp_t=p[i].to_h*3600+p[i].to_m*60+p[i].to_s;
		p[i].sum=temp_t-temp_f;
	}
	sort(p,p+n,cmp_open);
	printf("OPEN:%s %02d:%02d:%02d",p[0].ID,p[0].from_h,p[0].from_m,p[0].from_s);
	hh=p[0].from_h;mm=p[0].from_m;ss=p[0].from_s;
	temp=1;
	while(p[temp].from_h==hh&&p[temp].from_m==mm&&p[temp].from_s==ss)
	{
		printf(" %s %02d:%02d:%02d",p[temp].ID,p[temp].from_h,p[temp].from_m,p[temp].from_s);
		temp++;
	}
	printf("\n");
	sort(p,p+n,cmp_close);
	printf("CLOSE:%s %02d:%02d:%02d",p[0].ID,p[0].to_h,p[0].to_m,p[0].to_s);
	hh=p[0].to_h;mm=p[0].to_m;ss=p[0].to_s;
	temp=1;
	while(p[temp].to_h==hh&&p[temp].to_m==mm&&p[temp].to_s==ss)
	{
		printf(" %s %02d:%02d:%02d ",p[temp].ID,p[temp].to_h,p[temp].to_m,p[temp].to_s);
		temp++;
	}
	printf("\n");
	sort(p,p+n,cmp_star);
	temp=1;
	int tempsum=p[0].sum;
	while(p[temp].sum==tempsum)
		temp++;
	for(int i=0;i<temp;i++)
	{
		if(p[i].to_s<p[i].from_s)
		{
			ss=60+(p[i].to_s-p[i].from_s);
			tag=1;
		}
		else
		{
			ss=p[i].to_s-p[i].from_s;
			tag=0;
		}
		if(p[i].to_m<p[i].from_m+tag)
		{
			mm=60+(p[i].to_m-p[i].from_m-tag);
			tag=1;
		}
		else
		{
			mm=p[i].to_m-p[i].from_m-tag;
			tag=0;
		}
		if(p[i].to_h<p[i].from_h+tag)
		{
			hh=60+(p[i].to_h-p[i].from_h-tag);
			tag=1;
		}
		else
		{
			hh=p[i].to_h-p[i].from_h-tag;
			tag=0;
		}
		if(i==0)
			printf("STAR:%s %02d:%02d:%02d",p[i].ID,hh,mm,ss);
		else printf(" %s %02d:%02d:%02d ",p[i].ID,hh,mm,ss);
	}
	printf("\n");
}

题目3:有一个m×n的材料和一个s×t的模板,从材料中切除模板,求最大能切出来的模板的数量。
之前做了一种方式太暴力了,以至于一定会超时,所以我想着能不能用贪心来做。以下是我的思路,不知道对错,如果有错,希望可以指正。在一楼评论的帮助下,我对这题的代码和思路进行了重新的修改。
思路:
1.输入子母模板
2.用getpoint()找到母模板上所有子模板的左上角坐标,存入结构体point,注意一点,这里找到的子模板的坐标是按照先x从小变大,在x相等的情况下,y从小变大的顺序来的(这点可以自己体会)。
3.tag是标记数组,标记是否已经被占用
4.用DFS来遍历,子模板选或者不选,其中如果可以选的判断条件是被选中的子模板四个角的tag都是false。
5.输出最大的max_num

#include<stdio.h>//找到所有的子模板位置
#include<string.h> 
#include<algorithm>
using namespace std; 
#define MAX 100
char map_mom[MAX][MAX],map_son[MAX][MAX];
struct point//记录子模板的左上角的点的位子 
{
	int x,y;
}p[100];
struct Tag{
	bool tag[MAX][MAX];
};
int m,n,s,t;
int max_num;
int cnt;//记录字母表的数量,并且p数组按照x,y升序,其中x小的在前,然后y小的在前 
bool judge(int x,int y)
{
	for(int i=0;i<s;i++) 
		for(int j=0;j<t;j++)
			if(map_mom[i+x][j+y]!=map_son[i][j])
				return false;
	return true;
}
void getpoint()
{
	cnt=0;
	for(int i=0;i+s<=m;i++)
		for(int j=0;j+t<=n;j++)
			if(judge(i,j))
			{
				p[cnt].x=i;
				p[cnt].y=j;
				cnt++;
			}
}
Tag marktag(int x,int y,Tag ta)
{
	for(int i=x;i<x+s;i++)
		for(int j=y;j<y+t;j++)
			ta.tag[i][j]=true;
	return ta;
} 
void DFS(int n,Tag ta,int num)//第n个子模板加入或者不加入 
{
	if(num>max_num)
		max_num=num;
	if(n<cnt&&num+(cnt-n)>max_num)//num+(cnt-n)>max_num如果后面的个数加上现在已经有的可能比max多 
	{
		int px,py;
		px=p[n].x;py=p[n].y;
		DFS(n+1,ta,num);
		if(!ta.tag[px][py]&&!ta.tag[px+s-1][py]&&!ta.tag[px][py+t-1]&&!ta.tag[px+s-1][py+t-1])//四个角都没有被填充过,可以说明这个位置可以要 
		{
			ta=marktag(px,py,ta);
			DFS(n+1,ta,num+1);
		}
	}
}
int main()
{
	int i,j;
	Tag ta;
	while(scanf("%d %d",&m,&n)!=EOF)
	{
		max_num=0;
		for(i=0;i<m;i++)
			for(j=0;j<n;j++)
			{
				getchar();
				scanf("%c",&map_mom[i][j]);
			}
		scanf("%d %d",&s,&t);
		for(i=0;i<s;i++)
			for(j=0;j<t;j++)
			{
				getchar();
				scanf("%c",&map_son[i][j]);
			}
		getpoint();
		memset(ta.tag,false,sizeof(ta.tag));
		DFS(0,ta,0);
		printf("%d\n",max_num); 
	}
	return 0;
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值