练习赛1(补题)

问题 E: 一家人

题目描述

最近zzq交了一个新朋友叫cj,他们在聊天的时候发现500年前他们竟然是一家人!现在zzq想知道cj是他的长辈,晚辈,还是兄弟。

输入

输入包含多组测试数据。每组首先输入一个整数N(N<=10),接下来N行,每行输入两个整数a和b,表示a的父亲是b(1<=a,b<=20)。zzq的编号为1,cj的编号为2。
输入数据保证每个人只有一个父亲。

输出

对于每组输入,如果cj是zzq的晚辈,则输出“You are my younger”,如果cj是zzq的长辈,则输出“You are my elder”,如果是同辈则输出“You are my brother”。

样例输入

5
1 3
2 4
3 5
4 6
5 6
6
1 3
2 4
3 5
4 6
5 7
6 7

样例输出

You are my elder
You are my brother

比赛时忽略了无序这一重要条件,导致错误。补题时参考了小伙伴们的思路,找到了种比较好的方法,如下。

用一维数组实现父亲查找
#include<stdio.h>
#include<string.h>

int main()
{
	int a,b;
	int n,i;
	int k1,k2,sum1,sum2;
	int num[30];
	while(scanf("%d",&n)!=EOF)
	{
		memset(num,0,sizeof(num));
		for(i = 1; i <= n; i ++)
		{
			scanf("%d%d",&a,&b);
			num[a] = b;
		}
		k1 = 1;
		sum1 = 1;
		while(num[k1])
		{
			sum1++;
			k1 = num[k1];
		}
		k2 = 2;
		sum2 = 1;
		while(num[k2])
		{
			sum2++;
			k2 = num[k2];
		}
		if(sum1 > sum2)
			printf("You are my elder
");
		else if(sum1 == sum2)
			printf("You are my brother
");
		else
			printf("You are my younger
");
	}
	return 0;
}

问题 F: 马的移动

题目描述

zzq很喜欢下国际象棋,一天,他拿着国际象棋中的“马”时突然想到一个问题:
给定两个棋盘上的方格a和b,马从a跳到b最少需要多少步?
现请你编程解决这个问题。

提示:国际象棋棋盘为8格*8格,马的走子规则为,每步棋先横走或直走一格,然后再往外斜走一格。

输入

输入包含多组测试数据。每组输入由两个方格组成,每个方格包含一个小写字母(a~h),表示棋盘的列号,和一个整数(1~8),表示棋盘的行号。

输出

对于每组输入,输出一行“To get from xx to yy takes n knight moves.”。

样例输入

e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6

样例输出

To get from e2 to e4 takes 2 knight moves.
To get from a1 to b2 takes 4 knight moves.
To get from b2 to c3 takes 2 knight moves.
To get from a1 to h8 takes 6 knight moves.
To get from a1 to h7 takes 5 knight moves.
To get from h8 to a1 takes 6 knight moves.
To get from b1 to c3 takes 1 knight moves.
To get from f6 to f6 takes 0 knight moves.

BFS模板题,需要注意的是,当起始点和终止点相同时,不能直接输出,而应该特殊判断后输出

#include<stdio.h>
#include<string.h>
struct note{
	int x,y,s;
};

struct note que[100];
int main()
{
	char s1[3],s2[3];
	int head,tail;
	int i;
	int sx,sy,ex,ey;
	int book[10][10];
	int tx,ty,flag;
	int next[8][2] = {2,1,2,-1,-2,1,-2,-1,1,2,1,-2,-1,-2,-1,2};
	while(scanf("%s%s",s1,s2)!=EOF)
	{
		memset(book,0,sizeof(book));
		flag = 0;
		sx = s1[0] - 'a';
		sy = s1[1] - '1';
		ex = s2[0] - 'a';
		ey = s2[1] - '1';
		head = 1;
		tail = 1;
		que[tail].x = sx;
		que[tail].y = sy;
		que[tail].s = 0;
		tail ++;
		while(head < tail)
		{
			for(i = 0; i < 8; i ++)
			{
				tx = que[head].x + next[i][0];
				ty = que[head].y + next[i][1];
				if(tx < 0||tx > 7||ty < 0||ty > 7)
					continue;
				if(!book[tx][ty])
				{
					book[tx][ty] = 1;
					que[tail].x = tx;
					que[tail].y = ty;
					que[tail].s = que[head].s + 1;
					tail ++;
				}
				if(tx == ex&&ty == ey)
				{
					flag = 1;
					break;
				}
			}
			if(flag == 1)
				break;
				head ++;
		}
		if(ex == sx&&ey == sy)
			printf("To get from %s to %s takes 0 knight moves.
",s1,s2 );
		else
		   printf("To get from %s to %s takes %d knight moves.
",s1,s2,que[tail-1].s );
	}
	return 0;
}


问题 H: N的N次方

题目描述

现给你一个正整数N,请问N^N的最左边的数字是什么?

输入

输入包含多组测试数据。每组输入一个正整数N(N<=1000000)。

输出

对于每组输入,输出N^N的最左边的数字。

样例输入

3
4

样例输出

2
2

思路:

求最左边的数,范围在1000000,即要保证不超过范围,又要保证在运算过程中不丢失精度,易想到double。在最后需要特殊处理,保证输出只有一位数
#include<stdio.h>

int main()
{
	double m,n;
	int i;
	while(scanf("%lf",&n)!=EOF)
	{
		m = 1;
		for(i = 1; i <= (int)n; i ++)
		{
			m = m*n;
			if(m > 1000000)
				m /= 1000000;
		}
		while(m >= 10)
		{
			m/= 10;
		}
		printf("%d
",(int)m);
	}
	return 0;
 } 




原文地址:https://www.cnblogs.com/hellocheng/p/7350122.html