以下文字摘自《靈機一動·好玩的數學》:“狼人殺”遊戲分爲狼人、好人兩大陣營。在一局“狼人殺”遊戲中,1 號玩家說:“2 號是狼人”,2 號玩家說:“3 號是好人”,3 號玩家說:“4 號是狼人”,4 號玩家說:“5 號是好人”,5 號玩家說:“4 號是好人”。已知這 5 名玩家中有 2 人扮演狼人角色,有 2 人說的不是實話,有狼人撒謊但並不是所有狼人都在撒謊。扮演狼人角色的是哪兩號玩家?
本題是這個問題的升級版:已知 N 名玩家中有 2 人扮演狼人角色,有 2 人說的不是實話,有狼人撒謊但並不是所有狼人都在撒謊。要求你找出扮演狼人角色的是哪幾號玩家?
輸入格式:
輸入在第一行中給出一個正整數 N(5≤N≤100)。隨後 N 行,第 i 行給出第 i 號玩家說的話(1≤i≤N),即一個玩家編號,用正號表示好人,負號表示狼人。
輸出格式:
如果有解,在一行中按遞增順序輸出 2 個狼人的編號,其間以空格分隔,行首尾不得有多餘空格。如果解不唯一,則輸出最小序列解 —— 即對於兩個序列 A=a[1],...,a[M] 和 B=b[1],...,b[M],若存在 0≤k<M 使得 a[i]=b[i] (i≤k),且 a[k+1]<b[k+1],則稱序列 A 小於序列 B。若無解則輸出 No Solution。
輸入樣例 1:
5
-2
+3
-4
+5
+4
輸出樣例 1:
1 4
輸入樣例 2:
6
+6
+3
+1
-5
-2
+4
輸出樣例 2(解不唯一):
1 5
輸入樣例 3:
5
-2
-3
-4
-5
-1
輸出樣例 3:
No Solution
ps:這道題卡了很長時間,主要是要轉變思維方式,首先不是找出來誰說謊,關鍵是找出來兩個狼人,其次,用兩重循環暴力解決即可,起先我總是想着怎麼找規律,紙上畫來畫去,還是暴力解決來的方便。還有用c++會比c方便很多,要補習c++的知識,尤其是stl那塊。
找了一個博客寫的非常好,直接搬運了。
起初讀完題目知道題目的意思是這樣的:
N個人有兩個狼人,有2個說謊者;
2個說謊者中一個是狼人,一個是好人;
但是還是沒有具體的思路,後來看懂之後感覺其實也挺簡單。思路是這樣的:由於不知道誰是狼人,因此可以採用計算思維 ,逐個進行驗證,反正不缺算力,這對於習慣公式和推導的非計算機專業的理工科學生有時候真的想不到……
首先將數據存起來,存入vector型數組v(n+1),設定i/j兩個變量是狼人,i從1~n(由於很多參考算法採用vector都是從1開始存儲的,因此也就從1~n了,從0~n-1也是一樣的,只不過1~n比較方便),是外層for循環,j從i+1~n,是內層for循環。循環之前,先申請個vector數組a(N+1,1),也就是n+1個數組元素的值都是1,這裏a數組元素的值爲1表示是好人,爲-1表示是狼人,因此由於我們用i,j表示狼人,還需要將a[i]=a[j]=-1才行。同時還需要申請一個lie的vector,因爲要往裏面存入說謊者,由於不知道有幾個,因此直接用vector就好,不用vector數組。這裏顯示了vector作爲C++中動態數組的好處了,妙呀!!!如果有說謊者就存入lie,利用lie.push_back()就可以。
下面就需要知道如何判斷說謊者的條件:
自己說別人是狼人(v[k]<0),然而別人並不是狼人(a[abs(v[k])] == 1)
自己說別人不是狼人(v[k]>0),然而別人就是狼人(a[abs(v[k])] == -1)
即:v[k]*a[abs(v[k])] < 0
只要指定判斷說謊者的條件,即兩個說謊者且其中一個爲狼人(lie.size()==2&&a[lie[0]]+a[lie[1]]==0),滿足此條件輸出即可。由於遍歷的順序是從1~n,自然會滿足最小序列的要求。滿足條件輸出此時的 i,j(我們之前不是讓他倆當狼嘛~~~),如果都不滿足,輸出 No Solution。
作者:空天遮陽傘
來源:CSDN
原文:https://blog.csdn.net/zhanshe...
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!
代碼:
include <iostream>
include <stdio.h>
include <vector>
include <cmath>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int> v(n+1);
for(int i = 1; i <= n; i++)
cin>>v[i];
for(int i = 1; i <= n; i++){
for(int j = i+1; j<=n; j++){
vector<int> lie,a(n+1,1);
a[i]=a[j]=-1;
for(int k = 1; k <=n; k++)
if(v[k]*a[abs(v[k])] < 0)
lie.push_back(k);
if(lie.size() == 2 && a[lie[0]] + a[lie[1]] == 0){
cout<<i<<" "<<j;
return 0;
}
}
}
cout<<"No Solution";
return 0;
}