結果
| 問題 |
No.532 Possible or Impossible
|
| コンテスト | |
| ユーザー |
ei1333333
|
| 提出日時 | 2017-06-23 22:43:46 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 2,000 ms |
| コード長 | 2,530 bytes |
| コンパイル時間 | 1,241 ms |
| コンパイル使用メモリ | 160,732 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-10-03 03:12:53 |
| 合計ジャッジ時間 | 2,012 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 23 |
コンパイルメッセージ
main.cpp: In function ‘void fr_op(frac, frac, frac*, int)’:
main.cpp:13:52: warning: ‘nume’ may be used uninitialized in this function [-Wmaybe-uninitialized]
13 | long long gcd(long long p, long long q) { return q ? gcd(q, p % q) : p; }
| ~~^~~~~~~~~~~~~~~~~~~
main.cpp:17:19: note: ‘nume’ was declared here
17 | long long deno, nume, d;
| ^~~~
main.cpp:49:3: warning: ‘deno’ may be used uninitialized in this function [-Wmaybe-uninitialized]
49 | if(d == 0)d = 1;
| ^~
ソースコード
#include<bits/stdc++.h>
using namespace std;
typedef struct
{
long long nume;
long long deno;
} frac;
long long target;
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;
target = M;
return (check(num, N));
}
int main()
{
int N, M;
cin >> N >> M;
if(N >= 8 || (N <= 5 && check(N, M))) {
cout << "Possible" << endl;
} else {
cout << "Impossible" << endl;
}
}
ei1333333