题解 P8045 [COCI2015-2016#4] HAN
很显然,这是一道模拟题。
所以我写了一个简单易懂的代码,希望大家喜欢~
模拟还不是个 OIer 都会?
题目传送门
题目分析:
拿到这道题以后首先该怎样想呢?
其实这是一道很简单的题目,不要想复杂。
推导方式很简单,我们的思路只要跟着题目的要求走,大体的做法也就出来了。
首先,
题目中要求的是数到第
我们再设置一个变量
其次,
数字母时有顺逆时针的顺序,所以在设置一个判断顺逆时针的变量。
然后,
因为题目中说明了数据保证对于所有
最后,
理清你的思路,可以开始写动手写了!
这里有一些特殊情况需要考虑:
-
开头时的
now 的初始值一定要为0 ,并且在后面需要特判(这是因为有一种一开始就反向念字母的情况)。 -
在每次模拟时,从上一次结束的位置开始。我为此专门设置了一个变量。
-
计数要在反转和输出之前(具体见核心代码)。
初始化:
为了方便起见,我们分别把
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;
}
总结:
总的来说这道题还算比较简单,其实只要理清思路,就很好解了。
需要注意的是循环的范围一定要想清楚,多一少一都会出大差错。
后记:
这是萌新第一次写题解,可能有不足之处,如果大家有要我补充的或改进的,一定要提出来!谢谢大家。