Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

dh-winternagi 님의 블로그

(3955) 캔디 분배 본문

백준 (C++)/Solve

(3955) 캔디 분배

dh-winternagi 2026. 4. 24. 13:35

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

단계별로 풀어보기

45단계(수학 2) 1번째

 

 

 

구매하려는 사탕 개수를 Y라고 하면 Y*C=K*X+1이다.

따라서 aX+bY에서 a=-K, b=C로 두고 확장 유클리드 알고리즘을 쓰면 된다.

 

코드에서 루프가 끝난 뒤 r.first는 -K와 C의 최대공약수, s.first와 t.first는 X와 Y의 특수해이다.

-K와 C의 최대공약수가 1이 아니라면 정수해가 없으므로 불가능하고,

최대공약수가 음수라면 계산 편의를 위해 전부 양수로 바꾸어준다.

문제의 특성을 생각하면 X(나눠주는 사탕)와 Y(구매하는 사탕 봉지)는 10^9 이하의 양수가 되어야 한다.

이때 X와 Y의 일반해는 X'=X+nC, Y'=Y+nK이다. n의 값을 적절히 조절해 해가 유효 범위 내 들어올 수 있도록 하고, 할 수 없다면 불가능을 출력한다.

 

 

 

#include <iostream>
using namespace std;
#define MAX 1000000000

void solve(){
  long k, c;
  
  cin >> k >> c;
  
  long q;
  pair<long, long> r= {-k, c};
  pair<long, long> s= {1, 0};
  pair<long, long> t= {0, 1};
  
  while(r.second){
    q= r.first/r.second;
    r= {r.second, r.first-r.second*q};
    s= {s.second, s.first-s.second*q};
    t= {t.second, t.first-t.second*q};
  }
  
  if(abs(r.first)!=1){
    cout << "IMPOSSIBLE\n";
    return;
  }

  if(r.first==-1){
    s.first*= -1;
    t.first*= -1;
  }

  if(s.first>0){
    long n= min((s.first-1)/c, (t.first-1)/k);
    if(MAX<t.first-n*k){
      cout << "IMPOSSIBLE\n";
    }else{
      cout << t.first-n*k << "\n";
    }
  }else{
    long n= max((-s.first)/c, (-t.first)/k)+1;
    if(MAX<t.first+n*k){
      cout << "IMPOSSIBLE\n";
    }else{
      cout << t.first+n*k << "\n";
    }
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  
  int T;
  
  cin >> T;
  
  while(T--){
    solve();
  }
  
  return 0;
}

'백준 (C++) > Solve' 카테고리의 다른 글

(20412) 추첨상 사수 대작전! (Hard)  (0) 2026.04.24
(14565) 역원(Inverse) 구하기  (0) 2026.04.24
(1168) 요세푸스 문제 2  (0) 2026.04.24
(12899) 데이터 구조  (0) 2026.04.24
(16975) 수열과 쿼리 21  (0) 2026.04.24