Исходя из исходной программы из вопроса, я предлагаю подсчитывать кодировки только при достижении конца (if(start==end)
).
Поскольку func
всегда будет вызываться дважды с factor=1
и factor=2
, я могу свободно выбрать любое условие для подсчета.
Вот модифицированный код:
#include<bits/stdc++.h>
using namespace std;
int total = 0;
int arr[100001];
void func(int start,int end,int factor){
if(start==end) {
if(factor == 1) total++; // count once when reaching the end
return;
}
int j =start;
if((factor==2) && (j==end-1))//if j is the last element and factor is 2,accessing j+1 element is illegal
return;
if(factor==2){
if((arr[j]*10+arr[j+1])>26)
return;
else{
//total++;
func(start+2,end,1);
func(start+2,end,2);
}
}
else{//factor is 1
//total++;
func(start+1,end,1);
func(start+1,end,2);
}
return;
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int p;
cin>>p;
arr[i]=p;
}
func(0,n,1);
func(0,n,2);
cout<<total<<endl;
return 0;
}
Это вычисляет ожидаемые результаты из примера ввода в вопросе.
$ echo 5 2 5 1 1 4|./program
6
$ echo 10 3 3 3 3 3 3 3 3 3 3|./program
1
Есть возможности для улучшения.
Вместо изменения глобальной переменной я бы вернул число комбинаций из func
и добавил бы значения на более высоком уровне.
Я бы также обработал различие между 2-ди git и цифры 1-ди git в , называемые func
вместо номера вызывающего абонента.
Примерно так: псевдокод:
int func(int start, int end)
{
if(remaining length is <2) {
// we reached the end, so this is one combination
return 1;
}
if(two-digit number is >26) {
// only a 1-digit number is possible, count remaining combinations
return func(start+1, end);
}
// both a 1-digit or 2-digit number is possible, add the remaining combinations for both cases
return func(start+1) + func(start+2);
}