백준문제풀이

백준 1111번 IQ Test 문제풀이 c++

노가다 김씨 2022. 1. 25. 23:45

https://www.acmicpc.net/problem/1111

 

1111번: IQ Test

다음 수를 출력한다. 만약 다음 수가 여러 개일 경우에는 A를 출력하고, 다음 수를 구할 수 없는 경우에는 B를 출력한다.

www.acmicpc.net

문제해석

예를 들어 N=4인 수열 K1 K2 K3 K4가 주어졌을때

aK1+b=K2

aK2+b=K3

aK3+b=K4

를 만족하는 정수 a와 b를 구한 후 aK4+b를 출력하고 위 조건을 만족하는 정수 a, 정수 b가 없을경우 B를 aK4+b값이 둘이상의 값을 가지면 A를 출력하면 되는 문제이다.

 

일단 N=1일때는 다음으로 가질수있는 값이 여러개이므로 무조건 A를 출력한다.

 

N=2일때는 두 숫자가 같으면 다음 값도 두 숫자와 같은 숫자 단 하나로 결정되고

두 숫자가 다르다면 다음 값이 두개 이상의 값을 가질수 있으므로 A를 출력한다.

 

N이 3이상일때부터 설명하자면

arr[0]=K0,arr[1]=K1,arr[2]=K2,arr[3]=K3 , ........., arr[n]=Kn가 있다고 가정하면

인접한 두 수의 차이 K1-K0 , K2-K1 , K3-K2 ,....., Kn-kn-1 을 유심히 살펴보면

a(K1-K0)=K2-k1

a(K2-K1)=K3-k2

a(K3-K2)=K4-k3

......

a(Kn-1-Kn-2)=Kn-kn-1

이 됨을 찾을 수가 있다.

 

왜냐하면

aK0+b=K1

aK1+b=K2

에서 아래식에서 윗 식을빼면 

a(K1-K0)=K2-k1 이 식이 나오고

aK2+b=K3

aK3+b=K4

이것도 아래식에서 윗 식을빼면

a(K2-K1)=K3-k2 이렇게 나온다.

 

이렇게 인접한 두 수의 차이를 벡터 v에 넣어주게되면 벡터의 앞 원소부터 공비가 a인 등비 수열을 이루게 된다.

그렇다면 v[1]/v[0] 즉 a가 정수인가 정수가 아닌가 두가지 케이스를 따져야한다.

정수가 아니라면 B를 출력해야한다.

코드 부분의 if(a!=round(a))이 부분이 a가 정수인가를 판별하는 부분이 된다.

정수인경우에는 벡터의 끝까지 v[i+1]/v[i]가 a와 같은지 확인해야한다.

하나라도 v[i+1]/v[i] 이값이 같지 않을경우 B를 출력해야한다.

모든 v[i+1]/v[i]가 a와 같았다면 괜찮은 것이다.

 

드디어 숫자를 출력 할 수있는 기회가 온것 a는 이미 구했고 arr[0]과 arr[1]를 통해 b도 구할 수 있으므로 

a*arr[n-1]+b를 출력 하면 된다.

여기까지 일반적인 모든 경우를 출력 할 수있다.

 

아직 예외 처리를 하지않은 부분이 있는데 먼저 v[1]/v[0]에서 v[0]가 0일때이다.

v[0]이 0이고 v[1]이 0이 아닌경우 이건 말이 안된다.

예를들어 arr가 3 3 5 같은 경우이다 3a+b=3이면서 3a+b=5인경우는 없기때문에 B를 출력해야한다.

 

두번째는 v[0]이 0이고 v[1]이 0인경우이다.

arr가 3 3 3 같은 경우이다. 이때는 arr[0]에서 끝까지 같은지 확인해야한다 코드 부분의 check2()함수이다.

 

마지막으로 v[i+1]/v[i]를 확인할때이다.

4

1 0 0 0 같은 입력이 주어지면

v벡터에는 -1 0 0 이 들어가있는데 이때 0/0이 발생한다.

위에서 v[i+1]/v[i]가 a랑 같으면 괜찮았다고 했는데  v[i+1]이 0이고 v[i]이 0일때역시 괜찮다고 처리해주면 된다.

이 부분이 좀 헷갈려서 혼자 이해는 했는데 설명을 하려니 어떻게 설명해야할지 잘모르겠다...

 

코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
vector <double> v;
int check();
bool check2();
double arr[50];
int n;
int main(){
    cout.tie(NULL);
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cin>>arr[i];
    }
    if(n==1)
    {
        cout<<"A\n";
    }
    else if(n==2)
    {
        if(arr[0]==arr[1])
        {
            cout<<arr[0]<<"\n";
        }
        else
        {
            cout<<"A\n";
        }
    }
    else
    {
        for(int i=0; i<=n-2; i++)
        {
            v.push_back(arr[i+1]-arr[i]);
        }
        if(check()==1)
        {
            double a=v[1]/v[0];
            double b=arr[1]-a*arr[0];
            cout<<arr[n-1]*a+b<<"\n";
        }
        else if(check()==2)
        {
            if(check2()==true)
            {
                cout<<arr[0]<<"\n";
            }
            else
            {
                cout<<"B\n";
            }
        }
        else if(check()==0)
        {
            cout<<"B\n";
        }
    }
    return 0;
}
bool check2(){
    for(int i=0; i<=n-2; i++)
    {
        if(arr[i]==arr[i+1])
        {
            continue;
        }
        else
        {
            return false;
        }
    }
    return true;
}
int check(){
    if(v[0]==0&&v[1]==0)
    {
        return 2;
    }
    else if(v[0]==0&&v[1]!=0)
    {
        return 0;
    }
    else
    {
        double a=v[1]/v[0];
        if(a!=round(a))
        {
            return 0;
        }
        else
        {
            for(int i=1; i<=v.size()-2; i++)
            {
                if(a==v[i+1]/v[i]||(v[i+1]==0&&v[i]==0))
                {
                    continue;
                }
                else
                {
                    return 0;
                }
            }
        }
        return 1;
    }
}

 

0으로 나누는 부분의 예외 처리가 까다로웠음