SRM481 Div2 500

問題

卵が先か鶏が先か。予言者がn人に「卵」か「鶏」と言った。eggC人が卵と答えた。ただし予言者はlieC人には嘘をついた。んで、liarC人は聞いたことと逆の答えを答えた。「卵」か「鶏」か「曖昧」か「予言者が嘘ついてる」で答える。

考え方

嘘をついた人のうち何人が卵(または鶏)と答えたかわからないのでループをまわす。


まず、oracleが言ったのが「鶏」かどうか確認する。
嘘をついた人の中で鶏と答えた人がi人の場合、卵だと思っている人の人数は( ( eC-(liarC-i) ) + i)人となる。
卵だと思っている人数とoracleが嘘をついた人数lieC人が等しければ「鶏」と言った可能性がある。
ただし、左にはみ出す場合(liarC-i)>eCまたは右にはみ出す場合i>cCの時はちゃんと除外する。

「卵」の場合も同様にして計算できる。

bool isChicken(int n, int eC, int lieC, int liarC){
  for(int i=0;i<=liarC; i++){
    if(liarC-i>eC) continue; //これ重要
    if(i>n-eC) continue; //まじ重要
    if(eC-(liarC-i)+i==lieC) return true;
  }
  return false;
}
bool isEgg(int n, int cC, int lieC, int liarC){
  return isChicken(n, cC, lieC, liarC);
}

class ChickenOracle {
  public:
  string theTruth(int n, int eggCount, int lieCount, int liarCount) {
    bool cc = isChicken(n, eggCount, lieCount, liarCount);
    bool ee = isEgg(n, n-eggCount, lieCount, liarCount);
    if(cc==true && ee==true) return "Ambiguous";
    if(cc==true && ee==false) return "The chicken";
    if(cc==false && ee==true) return "The egg";
    return "The oracle is a lie";
  }
};
  • 反省

ちゃんと理解してなかった。そんな簡単な問題なわけがなかった。