G - 好老师
我想当一个好老师,所以我决定记住所有学生的名字。可是不久以后我就放弃了,因为学生太多了,根本记不住。但是我不能让我的学生发现这一点,否则会很没面子。所以每次要叫学生的名字时,我会引用离他最近的,我认得的学生。比如有10个学生:
A ? ? D ? ? ? H ? ?
想叫每个学生时,具体的叫法是:
位置 |
叫法 |
1 |
A |
2 |
right of A (A右边的同学)
扫描二维码关注公众号,回复:
2169018 查看本文章
|
3 |
left of D (D左边的同学) |
4 |
D |
5 |
right of D (D右边的同学) |
6 |
middle of D and H (D和H正中间的同学) |
7 |
left of H (H左边的同学) |
8 |
H |
9 |
right of H (H右边的同学) |
10 |
right of right of H (H右边的右边的同学) |
输入只有一组数据。第一行是学生数n(1<=n<=100)。第二行是每个学生的名字,按照从左到右的顺序给出,以空格分隔。每个名字要么是不超过3个英文字母,要么是问号。至少有一个学生的名字不是问号。下一行是询问的个数q(1<=q<=100)。每组数据包含一个整数p(1<=p<=n),即要叫的学生所在的位置(左数第一个是位置1)。
Output对于每个询问,输出叫法。注意"middle of X and Y"只有当被叫者有两个最近的已知学生X和Y,并且X在Y的左边。
Sample Input10A ? ? D ? ? ? H ? ?438610Sample Output
left of DHmiddle of D and Hright of rig ht of HHint
直接模拟情况就好了,要注意的是他们的优先级和一方搜不到的情况
离左边的近就直接输出“right of......”相同就输出“middle of ?and ?”只有唯一解。
注意到之一点就好了。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int main()
{
char s[1000][10];
int ss[1000];
int n,m,q,x,y,t,flag,ans,sum;
while(~scanf("%d",&n))
{
flag=0;
for(int i=1;i<=n;i++){
scanf("%s",s[i]);
if(s[i][0]!='?'){ss[i]=1;}//如果知道名字就标记1,也可以不标记标记是为了以后判断方便;
}
scanf("%d",&q);
for(int i=0;i<q;i++){
scanf("%d",&t);
x=-1;y=-1;ans=0;sum=0;
int len=strlen(s[t]);
if(s[t][0]!='?'){printf("%s\n",s[t]);continue;}//如果知道名字就输出名字,进入下一轮循环;
for(int j=1;t+j<=n;j++){if(ss[j+t]==1){x=j;break;}}//往后找到第一个知道名字的人,找到就用x记录下来,找不到就为-1;
for(int j=1;t-j>0;j++){if(ss[t-j]==1){y=j;break;}}//同理,往前找;
if(((x-y)>0&&y!=-1)||x==-1){//特别注意找不到的情况,容易忽略;
for(int j=0;j<y;j++){
printf("right of ");//输出左边有人知道名字且离被提问的人近的情况;
}
printf("%s",s[t-y]);
}
else if(y==-1||(x<y&&x!=-1)){//同理;
for(int j=0;j<x;j++){
printf("left of ");
}
printf("%s",s[x+t]);
}
else if(x==y){//输出在中间的情况
printf("middle of %s and %s",s[t-y],s[x+t]);
}
printf("\n");
}
}
return 0;
}