NOIP201605玩具謎題-解題報告

                                                                                   NOIP201605玩具謎題-解題報告c++

                                                                        2019-11-07       14:14         數組

Part 1原題:函數

 

小南有一套可愛的玩具小人,它們各有不一樣的職業。spa

 

有一天,這些玩具小人把小南的眼鏡藏了起來。小南發現玩具小人們圍成了一個圈,它們有的面朝圈內,有的面朝圈外。 以下圖:code

 

 

這時singer 告訴小南一個迷題:「眼鏡藏在我左數第 3 個玩具小人的右數第 1 個玩具小人的左數第 2 個玩具小人裏。 」
小南發現,這個迷題中玩具小人的朝向很是關鍵,由於朝內和朝外的玩具小人的左右方向是相反的:面朝圈內的玩具小人,它的左邊是順時針方向,右邊是逆時針方向;而面向圈外的玩具小人,它的左邊是逆時針方向,右邊是順時針方向。
小南一邊艱難地辨認着玩具小人,一邊數着:blog

「singer 朝內,左數第 3 個是archer。ci

「archer 朝外,右數第 1 個是thinker。字符串

「thinker 朝外,左數第 2 個是writer。get

「因此眼鏡藏在writer  這裏! 」
雖然成功找回了眼鏡,但小南並無放心。 若是下次有更多的玩具小人藏他的眼鏡,或是迷題的長度更長,他可能就沒法找到眼鏡了。 因此小南但願你寫程序幫他解決相似的迷題。這樣的迷題具體能夠描述爲:
有 n 個玩具小人圍成一圈,己知它們的職業和朝向。 如今第 1 個玩具小人告訴小 南一個包含 m 條指令的迷題,其中第 i 條指令形如「左數/右數第 si 個玩具小人」。 你須要輸出依次數完這些指令後,到達的玩具小人的職業。it

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;
}

註釋已經寫上了,各位本身能夠看。

相關文章
相關標籤/搜索