백준 16987 계란으로 계란치기

hyoJeong·2021년 5월 19일
0

이번에 풀 문제는 난이도 실버1에 해당하는 문제입니다.
문제:https://www.acmicpc.net/problem/16987

생각한 풀이방법:문제를 읽어보면, 계란을 선택할때는 왼쪽->오른쪽 방향으로 가고,
공격할 계란을 고를때는, 랜덤으로 어떤 계란이든 선택가능합니다.
모든 경우를 선택할, 백트래킹을 활용해 풀어보았습니다.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
int res;
int cnt;
int n;
struct a{
    int size,weight;
    a(int a,int b){
        size=a;
        weight=b;
    }
};
vector<a>v;
void bac(int l){
    if(l==n){
        cnt=0;
        for(int i=0;i<n;i++){
            if(v[i].size<=0){
                cnt++;
            }
        }
        res=max(res,cnt);
         
    }
    //잡은 계란이 깨진계란인경우
    if(v[l].size<=0){
        if(l+1<=n){
            bac(l+1);
        }
       
    }
    //위의 조건이 다 아닐경우
    else{
        //깰수 있는 계란이 있는지 유무 확인
        bool flag=false;
        //공격 당할 계란 무작위 선택
                for(int i=0;i<n;i++){
                    //내가 든 계란과 공격할 계란이 동일할경우 혹은 내가 공격할 계란이 이미 깨진 계란일 경우
                    if(l==i||v[i].size<=0){
                        //넘어감
                        continue;
                    }
                    //계란 깨기
                    v[l].size=v[l].size-v[i].weight;
                    v[i].size=v[i].size-v[l].weight;
                    flag=true;
                    //내가 선택한 계란의 오른쪽 계란집기
                    bac(l+1);
                    //원상복귀
                    v[l].size=v[l].size+v[i].weight;
                    v[i].size=v[i].size+v[l].weight;
                }
        //깰 계란이 없을경우 바로 n호출해 깨진 계란 확인하기
        if(!flag) bac(n);

        }

        
    
}


int main(){

  
    cin>>n;
    
    int size,weight;
    for(int i=0;i<n;i++){
        cin>>size>>weight;
        v.push_back(a(size,weight));
    }
    bac(0);
    cout<<res<<"\n";
    return 0;
   
}

각 코드마다 간단하게 주석을 달았으니, 코드와 같이 참고해서 보면 될거같아요~
혹시 이해가 안되거나, 궁금한 점이 있거나, 더 좋은 방법이 있다면 댓글남겨주세요😊👍

0개의 댓글