結果
| 問題 | 
                            No.532 Possible or Impossible
                             | 
                    
| コンテスト | |
| ユーザー | 
                             ei1333333
                         | 
                    
| 提出日時 | 2017-06-23 22:39:00 | 
| 言語 | C++11(廃止可能性あり)  (gcc 13.3.0)  | 
                    
| 結果 | 
                             
                                WA
                                 
                             
                            
                         | 
                    
| 実行時間 | - | 
| コード長 | 2,535 bytes | 
| コンパイル時間 | 1,267 ms | 
| コンパイル使用メモリ | 159,324 KB | 
| 実行使用メモリ | 6,820 KB | 
| 最終ジャッジ日時 | 2024-10-02 14:53:00 | 
| 合計ジャッジ時間 | 2,008 ms | 
| 
                            ジャッジサーバーID (参考情報)  | 
                        judge5 / judge1 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| other | AC * 20 WA * 3 | 
コンパイルメッセージ
main.cpp: In function ‘void fr_op(frac, frac, frac*, int)’:
main.cpp:14:52: warning: ‘nume’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   14 | long long gcd(long long p, long long q) { return q ? gcd(q, p % q) : p; }
      |                                                  ~~^~~~~~~~~~~~~~~~~~~
main.cpp:18:19: note: ‘nume’ was declared here
   18 |   long long deno, nume, d;
      |                   ^~~~
main.cpp:50:3: warning: ‘deno’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   50 |   if(d == 0)d = 1;
      |   ^~
            
            ソースコード
#include<bits/stdc++.h>
using namespace std;
typedef struct
{
  long long nume;
  long long deno;
} frac;
long long target;
int n;
frac num[10];
long long gcd(long long p, long long q) { return q ? gcd(q, p % q) : p; }
void fr_op(frac t0, frac t1, frac *ans, int op)
{
  long long deno, nume, d;
  switch(op) {
    case 0://足し算
      deno = t0.deno * t1.deno;
      nume = t0.nume * t1.deno + t1.nume * t0.deno;
      break;
    case 1://掛け算
      deno = t0.deno * t1.deno;
      nume = t0.nume * t1.nume;
      break;
    case 2://割り算1
      deno = t0.deno * t1.nume;
      nume = t0.nume * t1.deno;
      break;
    case 3://割り算2
      deno = t0.nume * t1.deno;
      nume = t0.deno * t1.nume;
      break;
    case 4://引き算
      if(t0.deno * t1.nume < t0.nume * t1.deno) {
        deno = t0.deno * t1.deno;
        nume = t0.nume * t1.deno - t1.nume * t0.deno;
      } else {
        deno = t0.deno * t1.deno;
        nume = t1.nume * t0.deno - t0.nume * t1.deno;
      }
      break;
      //0が発生するのは引き算の結果のみ
      //その直前には等式ができているのでその場合を分けてもいい
  }
  //約分
  d = gcd(deno, nume);
  if(d == 0)d = 1;
  //t0,t1がともに0だと割り算1,2の結果deno,numeがどちらも0になる
  (*ans).nume = nume / d;
  (*ans).deno = deno / d;
  return;
}
int check(frac *num, int count)
{
  int i, j, k, op;
  frac next[10], temp0, temp1;
  if(num[0].nume == target && num[0].deno == 1)return 1;
  //num[0]が求める値になっていればOK
  if(count == 1)return 0;
  //そうでなく要素数が1ならダメ
  for(i = 0; i < count - 1; i++)
    for(j = i + 1; j < count; j++) {
      //1.numから2数を取る
      //2.選んだ2数に四則のいずれかを施す
      //3.その結果をnum[0]に戻して再帰
      for(k = 0; k < count; k++)next[k] = num[k];
      temp0 = next[i];
      temp1 = next[j];
      next[i] = next[0];
      next[j] = next[count - 1];
      for(op = 0; op < 5; op++) {
        fr_op(temp0, temp1, &next[0], op);
        if(check(next, count - 1))return 1;
      }
    }
  return 0;
}
bool check(int N, int M)
{
  for(int i = 0; i < N; i++) num[i].nume = i + 1;
  for(int i = 0; i < N; i++) num[i].deno = 1;
  num[N].nume = M;
  num[N].deno = 1;
  n = N + 1;
  return(check(num, N));
}
int main()
{
  int N, M;
  cin >> N >> M;
  if(N >= 6 || (N <= 5 && check(N, M))) {
    cout << "Possible" << endl;
  } else {
    cout << "Impossible" << endl;
  }
}
            
            
            
        
            
ei1333333