从给定的真理和谎言的陈述中找到最诚实的人
给定一个大小为N * N的二进制矩阵, mat[][] 。单元格(i, j)的值表示第 i个人对第 j个人的评价。如果一个人x总是说实话,他就被认为是诚实的。如果人x有时说谎,有时说真话,那么他就是骗子。
- 如果 mat[i][j] = 0,那么第 i 个人说第 j 个人是骗子。
- 如果 mat[i][j] = 1,那么第 i 个人说第 j 个人是诚实的。
- 如果 mat[i][j] = 2,则第 i 个人不评论第 j 个人。
任务是找到最诚实的人。
例子:
Input: mat = {{2, 1, 2},
{1, 2, 2},
{2, 0, 2}}
Output: 2
Explanation: Each person makes a single statement.
Person 0 states that person 1 is honest.
Person 1 states that person 0 is honest.
Person 2 states that person 1 is liar.
Let’s take person 2 as the key.
- Assuming that person 2 is honest:
- Based on the statement made by person 2, person 1 is a liar.
- Now person 1 is liar and person 2 is honest.
- Based on the statement made by person 1, and since person 1 is liar, it could be:
- true. There will be a contradiction in this case and this assumption is invalid.
- lie. In this case, person 0 is also a liar and lied.
- Following that person 2 is honest, there can be only one honest person.
- Assuming that person 2 is liar:
- Based on the statement made by person 2, and since person 2 is liar, it could be:
- true. Following this scenario, person 0 and 1 are both liar as explained before.
- Following that person 2 is liar but told the truth, there will be no honest person.
- lying. In this case person 1 is honest.
- Since person 1 is honest, person 0 is also honest.
- Following that person 2 is liar and lied, there will be two honest persons.
- Based on the statement made by person 2, and since person 2 is liar, it could be:
- At most 2 persons are honest in the best case.
- So the answer is 2.
Input: mat = {{2, 0},
{0, 2}}
Output: 1
方法: N个人的意见可以有2 N种组合。这个想法是考虑2 N 数字并将它们的二进制表示假定为人们现实的可能顺序。 0位代表人是骗子, 1位代表人是诚实的。遍历所有数字,如果数字中的某个位为1 ,则假设被索引的人是诚实的,然后确认该假设。为了确认假设,请验证该数字的所有第 j位与该索引有关的内容以及他对矩阵中第 j个人的说法。请按照以下步骤操作:
- 获取矩阵的大小,即N 。
- 计算可能的总组合数。
- 遍历从0 到 2 N的所有数字。
- 检测此数字(组合)的二进制格式的 setbits(诚实),并递增计数器。
- 检查给定的“1”位是否暗示诚实或骗子。
- 一个人i如果他说谎是无效的。
- 如果第 j位在组合数中为0并且人i说j是诚实的。
- 如果第 j位在组合数中为1 ,并且我说j是一个巢穴。
- 如果人i有效,则更新答案。
下面是上述方法的实现。
C++
// C++ program to implement the above approach
#include
using namespace std;
// Utility Function
bool Is_Good(int n, int index)
{
return (n >> index) & 1;
}
// Function to count maximum honest persons
int MaximumHonest(vector >& mat)
{
int N = mat.size();
int ans = 0;
// Getting all the possible combinations
int comb = pow(2, N);
// Loop to find maximum honest persons
for (int i = 0; i < comb; i++) {
bool isValid = true;
int counter = 0;
for (int person = 0; person < N;
person++) {
// If the person is a liar
if (!Is_Good(i, person))
continue;
counter++;
// Checking validity of "persons"
// being honest and if "person"
// is honest then total number
// of honest persons
for (int j = 0; j < N; j++) {
if ((!Is_Good(i, j)
&& mat[person][j] == 1)
|| (Is_Good(i, j)
&& mat[person][j]
== 0)) {
isValid = false;
break;
}
}
}
if (isValid)
ans = max(ans, counter);
}
return ans;
}
// Driver code
int main()
{
vector > mat{ { 2, 0 },
{ 0, 2 } };
int res = MaximumHonest(mat);
cout << res;
return 0;
}
Java
// Java program to implement the above approach
import java.util.*;
class GFG{
// Utility Function
static boolean Is_Good(int n, int index)
{
return ((n >> index) & 1) >0?true:false;
}
// Function to count maximum honest persons
static int MaximumHonest(int [][] mat)
{
int N = mat[0].length;
int ans = 0;
// Getting all the possible combinations
int comb = (int) Math.pow(2, N);
// Loop to find maximum honest persons
for (int i = 0; i < comb; i++) {
boolean isValid = true;
int counter = 0;
for (int person = 0; person < N;
person++) {
// If the person is a liar
if (!Is_Good(i, person))
continue;
counter++;
// Checking validity of "persons"
// being honest and if "person"
// is honest then total number
// of honest persons
for (int j = 0; j < N; j++) {
if ((!Is_Good(i, j)
&& mat[person][j] == 1)
|| (Is_Good(i, j)
&& mat[person][j]
== 0)) {
isValid = false;
break;
}
}
}
if (isValid)
ans = Math.max(ans, counter);
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int [][]mat = { { 2, 0 },
{ 0, 2 } };
int res = MaximumHonest(mat);
System.out.print(res);
}
}
// This code is contributed by 29AjayKumar
Python3
# python3 program to implement the above approach
# Utility Function
def Is_Good(n, index):
return (n >> index) & 1
# Function to count maximum honest persons
def MaximumHonest(mat):
N = len(mat)
ans = 0
# Getting all the possible combinations
comb = pow(2, N)
# Loop to find maximum honest persons
for i in range(0, comb):
isValid = True
counter = 0
for person in range(0, N):
# If the person is a liar
if (not Is_Good(i, person)):
continue
counter += 1
# Checking validity of "persons"
# being honest and if "person"
# is honest then total number
# of honest persons
for j in range(0, N):
if ((not Is_Good(i, j)
and mat[person][j] == 1)
or (Is_Good(i, j)
and mat[person][j]
== 0)):
isValid = False
break
if (isValid):
ans = max(ans, counter)
return ans
# Driver code
if __name__ == "__main__":
mat = [[2, 0],
[0, 2]]
res = MaximumHonest(mat)
print(res)
# This code is contributed by rakeshsahni
Javascript
C#
// C# program to implement the above approach
using System;
class GFG {
// Utility Function
static bool Is_Good(int n, int index)
{
return ((n >> index) & 1) == 1;
}
// Function to count maximum honest persons
static int MaximumHonest(int[, ] mat)
{
int N = mat.GetLength(0);
int ans = 0;
// Getting all the possible combinations
int comb = (int)Math.Pow(2, N);
// Loop to find maximum honest persons
for (int i = 0; i < comb; i++) {
bool isValid = true;
int counter = 0;
for (int person = 0; person < N; person++) {
// If the person is a liar
if (!Is_Good(i, person))
continue;
counter++;
// Checking validity of "persons"
// being honest and if "person"
// is honest then total number
// of honest persons
for (int j = 0; j < N; j++) {
if ((!Is_Good(i, j)
&& mat[person, j] == 1)
|| (Is_Good(i, j)
&& mat[person, j] == 0)) {
isValid = false;
break;
}
}
}
if (isValid)
ans = Math.Max(ans, counter);
}
return ans;
}
// Driver code
public static void Main()
{
int[, ] mat = { { 2, 0 }, { 0, 2 } };
int res = MaximumHonest(mat);
Console.Write(res);
}
}
// This code is contributed by Samim Hossain Mondal.
1
时间复杂度: O(2 N * N * N)
辅助空间: O(1)