PTAワーウルフ
説明:
狼男(狼男杀)は、プレイヤーが狼男と人間の2つのパーティに分割されるゲームです。ゲームで、
プレイヤー#1は言った:「プレイヤー#2は狼男です。」;
プレーヤー#2は言った:「プレーヤー#3は人間です。」;
プレイヤー#3は言った:「プレイヤー#4は狼男です。」;
プレーヤー#4は言った:「プレーヤー#5は人間です。」; そして
プレーヤー#5は言った:「プレーヤー#4は人間です。」
その中に2人の狼男がいたことを考えると、少なくとも1人の狼男が嘘をついていましたが、すべてではありませんでした。狼男を指摘できますか?
ここで、この問題のより難しいバージョンを解決するように求められます。N人のプレーヤーがいて、その中にM人の狼男がいるとすると、少なくとも1人の狼男が嘘をついていて、正確にL人の嘘つきがありました。あなたは狼男を指摘することになっています。
入力仕様:
各入力ファイルには、1つのテストケースが含まれています。いずれの場合も、最初の行は3つの正の整数N(5≤N≤100)、MおよびL(2≤M、L <N)を示します。次に、N行が続き、i番目の行はi番目のプレーヤー(1≤i≤N)のステートメントを示します。これは、人間の正の符号と狼男の負の符号を持つプレーヤーのインデックスで表されます。 。
出力仕様:
解決策が存在する場合は、M人の狼男のインデックスを降順で1行に印刷します。数字は、行の先頭または末尾に余分なスペースを入れずに、正確に1つのスペースで区切る必要があります。複数の解がある場合は、最大の解シーケンスを出力する必要があります。つまり、2つのシーケンスA = {a [1]、…、a [M]}およびB = {b [1]、…、b [ M]}、a [i] = b [i](i≤k)およびa [k + 1]> b [k + 1]となる0≤k<Mが存在する場合、Aはより大きいと言われますBより。解決策がない場合は、単に「解決策なし」と印刷してください。
サンプル入力1:
5 2 2
-2
+3
-4
+5
+4
サンプル出力1:
4 1
サンプル入力2:
6 2 3
-2
+3
-4
+5
+4
-3
サンプル出力2:
6 4
サンプル入力3:
6 2 5
-2
+3
-4
+5
+4
+6
サンプル出力3:
No Solution
アイデア:
タイトルによると、最終的な出力がオオカミのラベルであることを見つけるのは難しいことではありません。ですから、私たちはオオカミを見つけることを基本的な目標としています。
手順は通常、次のアイデアに従います。
- n人のプレイヤーとm人のオオカミの組み合わせの数を生成します。
- 各状況が嘘つきの数と一致することを確認します。人数を超えたら、すぐに次のグループを確認してください。
- オオカミだけ
1
がm-1
嘘をついていることを確認します。 - 最終的な答えを出力します。
コード:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void backtrack(int n, int start, int m, vector<int>& path);
vector<vector<int>> res; // to store the combine
vector<vector<int>> combine(int n, int m) {
vector<int> path;
backtrack(n, n, m, path);
return res;
} // compute the combine
void backtrack(int n, int start, int m, vector<int>& path) {
if (path.size() == m) {
res.push_back(path);
return;
}
for (int i = start; i >= 1; --i) {
path.push_back(i);
backtrack(n, i-1, m, path);
path.pop_back();
}
}
int main() {
int n, m, l; // n for the total number of players, m for wolves, and l for liars
int m_count, l_count; // temporary to count wolves and liars
cin >> n >> m >> l;
m_count = m;
l_count = l;
vector<int> ass(n+1);
vector<vector<int>> result;
vector<int> pre(n+1, 1);
int t;
for (int i = 0; i < n; i++) {
// get players's assertions
cin >> t;
ass[i+1] = t;
}
combine(n, m);
int count = 0;
for (auto one: res) {
for (auto i: one) {
pre[i] = -1;
}
for (int i = 1; i <= n; i++) {
if (ass[i] * pre[abs(ass[i])] < 0) {
if (pre[i] == -1)
m_count--;
l_count--;
}
}
pre.assign(n + 1, 1);
if ((l_count != 0) || (m_count == 0) || (m_count == m)) {
l_count = l;
m_count = m;
count ++;
continue;
} else {
result.push_back(one);
l_count = l;
m_count = m;
}
}
if (count != res.size()) {
int s = result[0].size();
sort(result[0].rbegin(), result[0].rend());
for (int i = 0; i < s - 1; ++i) {
cout << result[0][i] << ' ';
}
cout << result[0][s - 1];
}
else {
cout << "No Solution";
}
}