问题 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\n");
else if(sum1 == sum2)
printf("You are my brother\n");
else
printf("You are my younger\n");
}
return 0;
}
问题 F: 马的移动
#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\n");
else if(sum1 == sum2)
printf("You are my brother\n");
else
printf("You are my younger\n");
}
return 0;
}
问题 F: 马的移动
题目描述
zzq很喜欢下国际象棋,一天,他拿着国际象棋中的“马”时突然想到一个问题:
给定两个棋盘上的方格a和b,马从a跳到b最少需要多少步?
现请你编程解决这个问题。
提示:国际象棋棋盘为8格*8格,马的走子规则为,每步棋先横走或直走一格,然后再往外斜走一格。
给定两个棋盘上的方格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.\n",s1,s2 );
else
printf("To get from %s to %s takes %d knight moves.\n",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\n",(int)m);
}
return 0;
}