NOIP201605玩具谜题-解题报告

                                                                                   NOIP201605玩具谜题-解题报告

                                                                        2019-11-07       14:14         

Part 1原题:

小南有一套可爱的玩具小人,它们各有不同的职业。

有一天,这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。 如下图:

 

这时singer 告诉小南一个迷题:“眼镜藏在我左数第 3 个玩具小人的右数第 1 个玩具小人的左数第 2 个玩具小人里。 ”
小南发现,这个迷题中玩具小人的朝向非常关键,因为朝内和朝外的玩具小人的左右方向是相反的:面朝圈内的玩具小人,它的左边是顺时针方向,右边是逆时针方向;而面向圈外的玩具小人,它的左边是逆时针方向,右边是顺时针方向。
小南一边艰难地辨认着玩具小人,一边数着:

“singer 朝内,左数第 3 个是archer。

扫描二维码关注公众号,回复: 7775742 查看本文章

“archer 朝外,右数第 1 个是thinker。

“thinker 朝外,左数第 2 个是writer。

“所以眼镜藏在writer  这里! ”
虽然成功找回了眼镜,但小南并没有放心。 如果下次有更多的玩具小人藏他的眼镜,或是迷题的长度更长,他可能就无法找到眼镜了。 所以小南希望你写程序帮他解决类似的迷题。这样的迷题具体可以描述为:
有 n 个玩具小人围成一圈,己知它们的职业和朝向。 现在第 1 个玩具小人告诉小 南一个包含 m 条指令的迷题,其中第 i 条指令形如“左数/右数第 si 个玩具小人”。 你需要输出依次数完这些指令后,到达的玩具小人的职业。

Part 2:思路

这道题目的关键是小人的朝向。

如果这些方向你都处理好了,那么就能AC了。

下面先粘一个超时代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct toy
 4 {
 5     int dir;
 6     char name[101];
 7 }a[10001];
 8 int i,j;
 9 int now;
10 int m,n;
11 int init()
12 {
13     int x=0,f=1;
14     char c=getchar();
15     while(c<'0'||c>'9')
16     {
17         if(c=='-') f=-1;
18         c=getchar();
19     }
20     while(c>='0'&&c<='9')
21     {
22         x=x*10+c-'0';
23         c=getchar();
24     }
25     return x*f;
26 }
27 int main()
28 {
29     n=init();
30     m=init();
31     for(i=0;i<n;i++)
32     {
33         a[i].dir=init();
34         scanf("%s",&a[i].name);
35     }
36     int x,y;
37     now=0;
38     for(i=1;i<=m;i++)
39     {
40         x=init();
41         y=init();
42         if(a[now].dir==0 && x==0) now=(now+n-y)%n;
43         else if(a[now].dir==0 && x==1) now=(now+y)%n;
44         else if(a[now].dir==1 && x==0) now=(now+y)%n;
45         else if(a[now].dir==1 && x==1) now=(now+n-y)%n;
46     }
47     printf("%s",&a[now].name);
48     return 0;
49 }

这个代码之所以超时,是因为它的处理部分(line43-45)的处理效率过低,下面粘AC代码:

#include<bits/stdc++.h>//万能头文件,这里偷了个懒 : ) 
using namespace std;//对于bits/stdc++.h来说,这句话是必要的,但对于某些头文件比如stdio.h来说,这句话不能写 
int main()//main函数 
{
    int n,m;//n个小人,m条线索 
    scanf("%d%d",&n,&m);//读入 
    bool a[100000];//这里的a[i]用来记录第i个小人的脸的朝向 
    char b[100000][11];//因为每个名字都是一个字符串,所以这里的b数组(串)要用二维的 
    for(int i=0;i<n;i++)//循环从1到n,循环输入每个小人 
    {
        scanf("%d%s",&a[i],&b[i]); 
    }
    int c[100000];//这里的c数组用来记录每条线索的的距离,例如 1 3中的3 
    for(int i=0;i<m;i++)//循环每条线索 
    {
        int t;//定义临时变量t,用来记录这条线索的行驶方向 
        cin>>t;//读入方向 
        cin>>c[i];//读入这条线索的距离 
        if(t==1) c[i]*=-1;    //这里,如果方向是 ‘右’,则将它乘上-1,方便后面累加和统计 
    }
    int pos=0;//定义位置变量(position),初始设为0 
    for(int i=0;i<m;i++)//循环每条线索进行处理 
    {
        if(a[pos]==0) c[i]*=-1;//如果小人方向是 ‘左’,则将它乘上-1,方便后面累计和统计 
        pos+=c[i];//对于每个线索,如果他的方向是左,那他的距离已经乘上-1了, 所以直接加上 
        if(pos>n-1) pos-=n;//如果他的越界方式是过于大,所以应该减去n,其功效类似于%n 
        if(pos<0) pos+=n;//如果他的越界方式是过于小,所以应该加上n,其功效类似于%n
    }
    cout<<b[pos];//输出当前位置上的小人的名字。 
    return 0;
}

注释已经写上了,各位自己可以看。

                             

猜你喜欢

转载自www.cnblogs.com/Monach/p/11811803.html