题解 P8045 [COCI2015-2016#4] HAN

· · 题解

很显然,这是一道模拟题。

所以我写了一个简单易懂的代码,希望大家喜欢~

模拟还不是个 OIer 都会?

题目传送门

题目分析:

拿到这道题以后首先该怎样想呢?

其实这是一道很简单的题目,不要想复杂。

推导方式很简单,我们的思路只要跟着题目的要求走,大体的做法也就出来了。

首先,

题目中要求的是数到第 n 个数时,字母 x 数过的次数,那自然要有计数的数组啦!

我们再设置一个变量 now 来记录现在走到了那一步。

其次,

数字母时有顺逆时针的顺序,所以在设置一个判断顺逆时针的变量。

然后,

因为题目中说明了数据保证对于所有 q 次命令,n 严格递增,所以我们的运算一定是与输入同时进行的。

最后,

理清你的思路,可以开始写动手写了!

这里有一些特殊情况需要考虑:

  1. 开头时的 now 的初始值一定要为 0,并且在后面需要特判(这是因为有一种一开始就反向念字母的情况)。

  2. 在每次模拟时,从上一次结束的位置开始。我为此专门设置了一个变量。

  3. 计数要在反转和输出之前(具体见核心代码)。

初始化:

为了方便起见,我们分别把 a,b,\cdots z 设为 0,1,\cdots 25

long long n=0,z[26]={0},now=0;
string s;
char ss;
bool sn=false;   //顺逆时针判断。

核心代码:

    long long m,mm=0;  //mm用来记录上一次结束的位置。
    for(int i=1;i<=n;i++){
        cin>>s;
        cin>>m;
        if(s[0]=='S'){  //只需要判断首字母就可以了。
            for(int j=mm+1;j<=m;j++){  
                if(sn==true){
                    now++;
                    if(i==1&&j==1){
                        now=0;
                    }
                    if(now==26){  //循环念字母。
                        now=0;
                    }
                }
                else {
                    if(i==1&&j==1){
                        now=1;
                    }
                    if(now==0){
                        now=26;
                    }
                    now--;
                }
                z[now]++;  //记录字母出现的个数。
            }
            sn=!sn;
        }
        else{
            for(int j=mm+1;j<=m;j++){  //这里实际上是我写复杂了,可以把循环放到判断语句的外面。
                if(sn==true){
                    now++;
                    if(now==26){
                        now=0;
                    }
                }
                else {
                    if(i==1&&j==1){
                        now=1;
                    }
                    if(now==0){
                        now=26;
                    }
                    now--;
                }
                z[now]++;
            }
            cin>>ss;
            cout<<z[ss-'a']<<endl;
        }
        mm=m;
    }

总结:

总的来说这道题还算比较简单,其实只要理清思路,就很好解了。

需要注意的是循环的范围一定要想清楚,多一少一都会出大差错。

后记:

这是萌新第一次写题解,可能有不足之处,如果大家有要我补充的或改进的,一定要提出来!谢谢大家。