2024. 5. 7. 22:53ㆍBOJ
문제

문제 설명
이 문제는 [a, b] 범위에 어떤 자연수 x가 있다고 한다면 x의 자릿수를 n자릿수라고 해봅시다. 첫 번째 자릿수에서 n번째 자릿수까지 x가 순서대로 증가하다가 감소만 하는 숫자를 카운팅 하는 문제입니다. 예를 들면 만약 x가 1234321이라면 x는 1~4까지 증가하다가 이후에는 오직 감소만 하기 때문에 x은 옳은 예제가 됩니다. 하지만 x가 1234322라면 1~4까지 증가하는 것은 맞지만 그 이후 부분에서 22는 감소하지 않기 때문에 틀린 예제가 됩니다.
문제 해설
기본적으로 120 미만의 숫자는 증가하다가 감소하는 숫자가 없기 때문에 120보다 작은 수는 0을 출력해 주었습니다.
if(m<120) {
cout<<0<<"\n";
}
만약 120보다 작지 않다면 탐색을 해주어야 하는데 저는 문자열을 이용하여서 증가하고 감소하는 문제를 해석하였습니다.
for(int i=120;i<=1000000;i++){
string s=to_string(i);
int k=s.size();
bool flag1=false,flag2=false,flag3=false;
for(int j=0;j<k-1;j++){
if(s[j]==s[j+1]) flag3=true;
else if(s[j]<s[j+1]){
if(!flag1&&!flag2) flag1=true;
else if(flag2){
dp[i]=0;
flag3=true;
break;
}
}
else if(s[j]>s[j+1]){
if(!flag2&&flag1) flag2=true;
else if(!flag1){
dp[i]=0;
flag3=true;
break;
}
else continue;
}
}
if(!flag3&&flag1&&flag2) dp[i]=1;
}
기본적으로 bool을 이용한 변수들을 이용하여서 탐색을 하였는데 flag1은 증가하는 경우에 true로 변경해 주고 flag2는 감소하는 경우에 true로 변경해 주고 마지막으로 flag3는 x가 틀린 경우에 true로 변경해 주었습니다.
젤 먼저 s [j]==s [j+1]이라면 바로 flag3을 true로 바꾸어 주었습니다.
if(s[j]==s[j+1]) flag3=true;
그다음으로 자릿수가 증가할수록 증가해야 하다가 감소해야 하기 때문에 두 가지를 조건을 이용하여서 이용하여서 결정하였습니다.
- 만약 증가도 감소도 하지 않은 상태라면 flag2를 true로 바꾸어주고 탐색을 진행해 준다.
- 하지만 flag2가 참, 즉 감소한 적이 있다면 flag3을 true로 바꾸어 준다.
감소하는 경우도 비슷하게 두 가지 경우로 결정하였습니다.
- 만약 flag1이 참이고 flag2가 거짓이면 flag2를 참으로 바꾸고 탐색을 이어간다.
- 하지만 flag1이 거짓이라면 바로 flag3을 참으로 바꾼다.
최종적으로 flag3가 거짓이고 flag1, flag2가 참이면 dp [x]를 +1 해주면 됩니다.
그 이후에는 120부터 백만까지 누적합을 이용하여서 개수를 카운팅 해주면서 모든 준비를 끝내주었습니다.
만약 [a, b]가 주어진다면 dp [b]-dp [a-1]을 정답으로 하여서 출력해 주면 됩니다.
최종 코드
#include<iostream>
using namespace std;
int n,m,t;
int dp[1000001];
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>t;
for(int i=120;i<=1000000;i++){
string s=to_string(i);
int k=s.size();
bool flag1=false,flag2=false,flag3=false;
for(int j=0;j<k-1;j++){
if(s[j]==s[j+1]) flag3=true;
else if(s[j]<s[j+1]){
if(!flag1&&!flag2) flag1=true;
else if(flag2){
dp[i]=0;
flag3=true;
break;
}
}
else if(s[j]>s[j+1]){
if(!flag2&&flag1) flag2=true;
else if(!flag1){
dp[i]=0;
flag3=true;
break;
}
else continue;
}
}
if(!flag3&&flag1&&flag2) dp[i]=1;
}
for(int i=1;i<=1000000;i++){
dp[i]+=dp[i-1];
}
while(t--){
cin>>n>>m;
if(m<120) {
cout<<0<<"\n";
}
else{
cout<<dp[m]-dp[n-1]<<"\n";
}
}
}
'BOJ' 카테고리의 다른 글
| 맛있는 사과 (BOJ 32963) (0) | 2025.01.28 |
|---|---|
| XOR (BOJ 14245) (0) | 2025.01.14 |
| Ignition(점화) (BOJ 13141) (1) | 2024.08.08 |
| 세금 (BOJ 13907번) (3) | 2024.07.22 |
| 도로포장 (BOJ 1162) (1) | 2024.07.20 |