您的位置:首页 > 理论基础

浙大计算机研究生复试上机考试-2009年

2012-02-09 20:13 417 查看
//hdu 3782 3783 3784 3785 3786

/************************************************************************/
/* xxx定律-hdu 3782

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 525    Accepted Submission(s): 438

Problem Description
对于一个数n,如果是偶数,就把n砍掉一半;如果是奇数,把n变成 3*n+ 1后砍掉一半,直到该数变为1为止。
请计算需要经过几步才能将n变到1,具体可见样例。

Input
测试包含多个用例,每个用例包含一个整数n,当n为0 时表示输入结束。(1<=n<=10000)

Output
对于每组测试用例请输出一个数,表示需要经过的步数,每组输出占一行。

Sample Input
3
1
0

Sample Output
5
0

Source
浙大计算机研究生复试上机考试-2009年                                                                     */
/************************************************************************/

#include "stdio.h"
#include"math.h"

int main()
{
	int a,b;
	while(scanf("%d",&a)!=EOF&&a)
	{
		int cnt=0;
		while (a!=1)
		{
			if(a%2)
			{
				a=a*3+1;
				a/=2;
			}
			else
				a/=2;
			cnt++;
		}
		printf("%d\n",cnt);
	}
}


/************************************************************************/
/* ZOJ hdu 3783

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 464    Accepted Submission(s): 353

Problem Description
读入一个字符串,字符串中包含ZOJ三个字符,个数不一定相等,按ZOJ的顺序输出,当某个字符用完时,剩下的仍然按照ZOJ的顺序输出。

Input
题目包含多组用例,每组用例占一行,包含ZOJ三个字符,当输入“E”时表示输入结束。
1<=length<=100。

Output
对于每组输入,请输出一行,表示按照要求处理后的字符串。
具体可见样例。

Sample Input
ZZOOOJJJ
ZZZZOOOOOJJJ
ZOOOJJ
E

Sample Output
ZOJZOJOJ
ZOJZOJZOJZOO
ZOJOJO

Source
浙大计算机研究生复试上机考试-2009年                                                                     */
/************************************************************************/

#include "iostream"
#include"string"
using namespace std;

int main()
{
	char str[105];
	while (scanf("%s",str)!=EOF&&strcmp(str,"E"))
	{
		int z,o,j;
		z=o=j=0;
		for (int i=0;i<strlen(str);i++)
		{
			if(str[i]=='Z')
				z++;
			else if(str[i]=='O')
				o++;
			else if (str[i]=='J')
				j++;
		}
		while (z>0||o>0|j>0)
		{
			if(z-->0)
				printf("Z");
			if(o-->0)
				printf("O");
			if (j-->0)
				printf("J");
		}
		printf("\n");
	}
}



/************************************************************************/
/* 继续xxx定律-hdu 3784

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 685    Accepted Submission(s): 197

Problem Description
当n为3时,我们在验证xxx定律的过程中会得到一个序列,3,5,8,4,2,1,将3称为关键数,5,8,4,2称为覆盖数。现在输入n个数字a[i],根据关键数与覆盖数的理论,我们只需要验证其中部分数就可以确定所有数满足xxx定律,输出输入的n个数中的关键数。如果其中有多个关键数的话按照其输入顺序的逆序输出。

Input
输入数据包含多个用例,每个用例首先包含一个整数n,然后接下来一行有n个整数a[i],其中:
1<=n<=500
1<a[i]<=1000

Output
请计算并输出数组a中包含的关键数,并按照其输入顺序的逆序输出,每个用例输出占一行。

Sample Input
3
3 8 4
5
3 8 4 7 15
5
3 8 4 15 7
0

Sample Output
3
15 7 3
7 15 3

Source
浙大计算机研究生复试上机考试-2009年
*/
/************************************************************************/

#include"iostream"
using namespace std;
#define  N 1010
int a
;
bool v[200000];
int main()
{
	int x,i,j,n;
	while (scanf("%d",&n)!=EOF&&n)
	{
		memset(v,false,sizeof(v));
		for (i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
			x=a[i];
			while (x!=1)
			{
				if(x%2)
				{
					x=x*3+1;
					x/=2;
				}
				else
					x/=2;
				v[x]=true;
			}
		}
		bool first=true;
		for (i=n-1;i>=0;i--)
		{
			if (!v[a[i]])
			{
				if(!first)
					cout<<" ";
				printf("%d",a[i]);
				first=false;
			}
			else
				continue;
		}
		printf("\n");
	}
}


/************************************************************************/
/* 寻找大富翁-hdu 3785

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 765    Accepted Submission(s): 413

Problem Description
浙江桐乡乌镇共有n个人,请找出该镇上的前m个大富翁.

Input
输入包含多组测试用例.
每个用例首先包含2个整数n(0<n<=100000)和m(0<m<=10),其中: n为镇上的人数,m为需要找出的大富翁数, 接下来一行输入镇上n个人的财富值.
n和m同时为0时表示输入结束.

Output
请输出乌镇前m个大富翁的财产数,财产多的排前面,如果大富翁不足m个,则全部输出,每组输出占一行.

Sample Input
3 1
2 5 -1
5 3
1 2 3 4 5
0 0

Sample Output
5
5 4 3

Source
浙大计算机研究生复试上机考试-2009年                                                                     */
/************************************************************************/

#include "iostream"
#include "algorithm"
using namespace std;

int a[100002];
int m,n;
int main()
{
	int i;
	while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
	{
		for (i=0;i<n;i++)
			scanf("%d",&a[i]);
		sort(a,a+n);
		printf("%d",a[n-1]);
		for (i=1;i<m;i++)
			printf(" %d",a[n-i-1]);
		cout<<endl;
	}
}


/************************************************************************/
/*3785- 寻找大富翁(寻找第k大的数)
*************************************************************************/
//the k max number
//@Author:zrq sophia
#include "iostream"
#include "algorithm"
using namespace std;

int a[100002];
int c[15];
int m,n;

int Partition(int left,int right,int k)//find array 中的第k大数
{
	int base=a[left];//basic element
	int l,r;
	l=left,r=right;
	while(l<r)
	{
		while(l<r&&a[r]>base)	r--;
		if(l<r)	
			a[l++]=a[r];
		while(l<r&&a[l]<=base)	l++;
		if(l<r)
			a[r--]=a[l];
	}
	a[l]=base;
	int index=right-r+1;//base在是第index大的数
	if(index>k)		
		return Partition(r+1,right,k);
	else if(index<k)
		return Partition(left,r-1,k-index);
	return base;
}

int main()
{
	int i;
	while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
	{
		for (i=0;i<n;i++)
			scanf("%d",&a[i]);
		int b= Partition(0,n-1,m);
		int j=0;
		for(i=0;i<n;i++)
		{
			if(a[i]>b)
				c[j++]=a[i];
		}
		bool flag=false;
		sort(c,c+j);
		if(j>=1)
		{
			printf("%d",c[j-1]);
			flag=true;
		}
		for(i=1;i<j;i++)
			printf(" %d",c[j-1-i]);
		if(!flag)
		{
			printf("%d",b);
			j++;
		}
		while(++j<=m)
			printf(" %d",b);

		cout<<endl;
	}
}


/************************************************************************/
/* 找出直系亲属

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 411    Accepted Submission(s): 171

Problem Description
如果A,B是C的父母亲,则A,B是C的parent,C是A,B的child,如果A,B是C的(外)祖父,祖母,则A,B是C的grandparent,C是A,B的grandchild,如果A,B是C的(外)曾祖父,曾祖母,则A,B是C的great-grandparent,C是A,B的great-grandchild,之后再多一辈,则在关系上加一个great-。

Input
输入包含多组测试用例,每组用例首先包含2个整数n(0<=n<=26)和m(0<m<50), 分别表示有n个亲属关系和m个问题, 然后接下来是n行的形式如ABC的字符串,表示A的父母亲分别是B和C,如果A的父母亲信息不全,则用-代替,例如A-C,再然后是m行形式如FA的字符串,表示询问F和A的关系。
当n和m为0时结束输入。

Output
如果询问的2个人是直系亲属,请按题目描述输出2者的关系,如果没有直系关系,请输出-。
具体含义和输出格式参见样例.

Sample Input
3 2
ABC
CDE
EFG
FA
BE
0 0

Sample Output
great-grandparent
-

Source
浙大计算机研究生复试上机考试-2009年

*/
/************************************************************************/
#include "iostream"
#include "string"
#include "algorithm"
using namespace std;
#define INF 1000000
#define min(a,b) a<b?a:b
char tree['Z'+10][2];

int Dfs(char a,char b,int level)
{
	//分别从a和b往下找
	if(a=='-'||tree[a][0]=='-'&&tree[a][1]=='-')
		return INF;
	if(tree[a][0]==b||tree[a][1]==b)
		return level+1;
	int left=Dfs(tree[a][0],b,level+1);
	int right=Dfs(tree[a][1],b,level+1);
	return min(left,right);
}
int main()
{
	string str;
	int n,m,i,j;
	while (scanf("%d%d",&n,&m)!=EOF&&!(n==0&&m==0))
	{
		memset(tree,'-',sizeof(char)*2*('Z'+10));
		for(i=0;i<n;i++)
		{
			cin>>str;
			tree[str[0]][0]=str[1];
			tree[str[0]][1]=str[2];
		}
		for(i=0;i<m;i++)
		{
			cin>>str;
			int level1=Dfs(str[0],str[1],0);
			int level2=Dfs(str[1],str[0],0);
			int level=level1>=INF?-level2:level1;
			if(abs(level)>=INF)
			{
				printf("-\n");
				continue;
			}
			while (level++<-2)
				printf("great-");
			level--;
			if(level==-1)
				printf("parent\n");
			else if(level==-2)
				printf("grandparent\n");

			while (level-->2)
				printf("great-");
			level++;
			if (level==2)
				printf("grandchild\n");
			else if(level==1)
				printf("child\n");
		}
	}
}


hdu 3786

//逆向思考更简单,建树可知每个node对应一个孩子,这里把孩子记为parent,只要顺着parent往上爬着找就行了
//@Author:zrq sophia
#include "iostream"
#include "stdio.h"
#include "string"
#include"memory.h"
#include "algorithm"
using namespace std;
#define INF 30
#define min(a,b) a<b?a:b
char parent['Z'+10];//这棵树中的parent与题目描述的父子关系正好相反

int cha(char c1,char c2)
{
	int level=0;
	while(c1!=c2&&c1!='-')
	{
		c1=parent[c1];
		level++;
	}
	if(c1=='-')
		return INF;
	return level;
}

int main()
{
	string str;
	int n,m,i,j;
	while (scanf("%d%d",&n,&m)!=EOF&&(n||m))
	{
		memset(parent,'-',sizeof(char)*('Z'+10));
		for(i=0;i<n;i++)
		{
			cin>>str;
			parent[str[1]]=str[0];
			parent[str[2]]=str[0];
		}
		for(i=0;i<m;i++)
		{
			cin>>str;
			int level1=cha(str[0],str[1]);
			int level2=cha(str[1],str[0]);
			int level=level2>=INF?-level1:level2;
			if(abs(level)>=INF||abs(level)==0)
			{
				printf("-\n");
				continue;
			}
			while (level++<-2)
				printf("great-");
			level--;
			if(level==-1)
				printf("parent\n");
			else if(level==-2)
				printf("grandparent\n");

			while (level-->2)
				printf("great-");
			level++;
			if (level==2)
				printf("grandchild\n");
			else if(level==1)
				printf("child\n");
		}
	}
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: