이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <iostream>
#include <vector>
#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
const long long MOD = 1e9+7;
vector<long long> v1;
long long dp[50][32][32][5][5];
long long rec(long long len,long long a,long long b,bool limit, int leading){
// cout<<len<<" "<<a<<" "<<b<<" "<<limit<<" "<<leading<<endl;
if(dp[len][a][b][limit][leading]!=-1){
return dp[len][a][b][limit][leading];
}
if(len >= v1.size()-1){
if(len == 3){
}
return 1;
}
if(limit){
//last digit added was the largest possible digit
dp[len][a][b][limit][leading] = 0;
for(long long i=0;i<=9;i++){
if(i>v1[len+1]){
//can't add a larger digit
break;
}
if(leading == 3 && i==0){
//a new digit was just added after a bunch of zeroes
if(i==v1[len+1]){
//largest possible digit I can add(Can add a 0, leading 0s don't count as a palindrome)
dp[len][a][b][1][leading] += rec(len+1,b,i,1,0);
dp[len][a][b][1][leading]%=MOD;
}else{
//can do the same thing
dp[len][a][b][1][leading] += rec(len+1,b,i,0,0);
dp[len][a][b][1][leading]%=MOD;
}
continue;
}
else if(leading ==3){
//a number that's not 0 is being added after a number that's just been added after a bunch of 0s
if((i!=a && i!=b) && i == v1[len+1]){
//if this number's not a palindrome and it's the largest possible digit to add, add it
dp[len][a][b][1][leading] += rec(len+1,b,i,1,0);
dp[len][a][b][1][leading]%=MOD;
continue;
}
else if(i!=a && i!=b){
//same as above, but it's not the larges possible digit to add
dp[len][a][b][1][leading] += rec(len+1,b,i,0,0);
dp[len][a][b][1][leading]%=MOD;
continue;
}
}
else if(leading && i==0){
//have leading 0s, want to add another 0
if(i==v1[len+1]){
//largest digit we can add is this 0(I don't think this case would actually exist)
dp[len][a][b][1][leading] += rec(len+1,b,i,1,1);
dp[len][a][b][1][leading]%=MOD;
}else{
//we add this 0 and continue (our current string is just a bunch of 0s)
dp[len][a][b][1][leading] += rec(len+1,b,i,0,1);
dp[len][a][b][1][leading]%=MOD;
}
continue;
}
else if(leading){
//we have a bunch of leading 0s and we want to add a non zero digit
if((i!=a && i!=b) && i == v1[len+1]){
//first 2 conditions will always hold true I think,the third is a check to see if this digit is the max digit we can add. If it is we shift our leading state to 3(dealt with above)
dp[len][a][b][1][leading] += rec(len+1,b,i,1,3);
dp[len][a][b][1][leading]%=MOD;
continue;
}
else if(i!=a && i!=b){
//Again first 2 conditions will always hold true
dp[len][a][b][1][leading] += rec(len+1,b,i,0,3);
dp[len][a][b][1][leading]%=MOD;
continue;
}
}
else if((i!=a && i!=b) && i == v1[len+1]){
//after a bunch of leading 0s(or none), we have a non zero digit + x more digits (where x+1>=2)
dp[len][a][b][1][leading] += rec(len+1,b,i,1,0);
dp[len][a][b][1][leading]%=MOD;
}
else if(i!=a && i!=b){
dp[len][a][b][1][leading] += rec(len+1,b,i,0,0);
dp[len][a][b][1][leading]%=MOD;
}
}
dp[len][a][b][limit][leading]%=MOD;
return dp[len][a][b][limit][leading];
}else{
dp[len][a][b][limit][leading] = 0;
for(long long i=0;i<=9;i++){
if(leading == 3 && i == 0){
dp[len][a][b][limit][leading] += rec(len+1,b,i,limit,0);
dp[len][a][b][limit][leading]%=MOD;
}else if(leading ==3){
if(i!=a && i!=b){
dp[len][a][b][limit][leading] += rec(len+1,b,i,limit,0);
dp[len][a][b][limit][leading]%=MOD;
}
}
else if(leading && i==0){
dp[len][a][b][limit][leading] += rec(len+1,b,i,limit,1);
dp[len][a][b][limit][leading]%=MOD;
continue;
}else if(leading){
dp[len][a][b][limit][leading] += rec(len+1,b,i,limit,3);
dp[len][a][b][limit][leading]%=MOD;
continue;
}
else if(i!=a && i!=b){
dp[len][a][b][limit][leading] += rec(len+1,b,i,limit,0);
dp[len][a][b][limit][leading]%=MOD;
}
}
dp[len][a][b][limit][leading]%=MOD;
return dp[len][a][b][limit][leading];
}
}
long long solve(long long curr){
v1.clear();
for(long long i=0;i<=49;i++){
for(long long j=0;j<=31;j++){
for(long long k=0;k<=31;k++){
for(long long l=0;l<=4;l++){
for(long long m=0;m<=4;m++){
dp[i][j][k][l][m] = -1;
}
}
}
}
}
while(curr){
v1.push_back(curr%10);
curr/=10;
}
v1.push_back(0);
reverse(v1.begin(),v1.end());
long long ans = 0;
for(long long i=0;i<=9;i++){
if(v1[1]<i){
break;
}
if(i ==0){
ans+=rec(1,30,0,false,true);
ans%=MOD;
// cout<<ans<<endl;
continue;
}
ans+=rec(1,30,i,v1[1] == i,false);
ans%=MOD;
//cout<<ans<<endl;
}
return ans;
}
int main(){
long long a,b;
cin>>a>>b;
cout<<solve(b)-solve(a-1)<<endl;
}
컴파일 시 표준 에러 (stderr) 메시지
numbers.cpp: In function 'long long int rec(long long int, long long int, long long int, bool, int)':
numbers.cpp:15:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if(len >= v1.size()-1){
~~~~^~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |