Find the most honest person from given statements of truths and lies
Last Updated :
09 Mar, 2022
Given a binary matrix of size N * N, mat[][]. Value at cell (i, j) indicates what ith person says about jth person. A person x is considered honest if he always tells the truth. If person x speaks lie sometimes and truth sometimes, then he is a liar.
- If mat[i][j] = 0, then ith person says jth person is a liar.
- If mat[i][j] = 1, then ith person says jth person is honest.
- If mat[i][j] = 2, then ith person does not comment about jth person.
The task is to find maximum honest persons.
Examples:
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.
- At most 2 persons are honest in the best case.
- So the answer is 2.
Input: mat = {{2, 0},
{0, 2}}
Output: 1
Approach: There can be 2N combinations of the opinions among N persons. The idea is to consider 2N numbers and assume their binary representation as the possible order of persons’ reality. 0 bit represents the person is liar and 1 represents the person is honest. Traverse through all numbers, if a bit in the number is 1 then assume that the indexed person is honest and then confirm this assumption. To confirm the assumption verify all jth bits of the number with respect to this index and what he says about jth person in the matrix. Follow the steps mentioned below:
- Get the size of the matrix i.e. N.
- Compute the number of total combinations possible.
- Iterate through all numbers from 0 to 2N.
- Detect the setbits (honest) in the binary format of this number (combination), and increment the counter.
- Check if the given “1” bit implies an honest or a liar.
- A person i is invalid if he lies.
- If jth bit is 0 in combination number and person i says that j is honest.
- if jth bit is 1 in combination number and person i says that j is a lair.
- If person i is valid, then update the answer.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
bool Is_Good( int n, int index)
{
return (n >> index) & 1;
}
int MaximumHonest(vector<vector< int > >& mat)
{
int N = mat.size();
int ans = 0;
int comb = pow (2, N);
for ( int i = 0; i < comb; i++) {
bool isValid = true ;
int counter = 0;
for ( int person = 0; person < N;
person++) {
if (!Is_Good(i, person))
continue ;
counter++;
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;
}
int main()
{
vector<vector< int > > mat{ { 2, 0 },
{ 0, 2 } };
int res = MaximumHonest(mat);
cout << res;
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean Is_Good( int n, int index)
{
return ((n >> index) & 1 ) > 0 ? true : false ;
}
static int MaximumHonest( int [][] mat)
{
int N = mat[ 0 ].length;
int ans = 0 ;
int comb = ( int ) Math.pow( 2 , N);
for ( int i = 0 ; i < comb; i++) {
boolean isValid = true ;
int counter = 0 ;
for ( int person = 0 ; person < N;
person++) {
if (!Is_Good(i, person))
continue ;
counter++;
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;
}
public static void main(String[] args)
{
int [][]mat = { { 2 , 0 },
{ 0 , 2 } };
int res = MaximumHonest(mat);
System.out.print(res);
}
}
|
Python3
def Is_Good(n, index):
return (n >> index) & 1
def MaximumHonest(mat):
N = len (mat)
ans = 0
comb = pow ( 2 , N)
for i in range ( 0 , comb):
isValid = True
counter = 0
for person in range ( 0 , N):
if ( not Is_Good(i, person)):
continue
counter + = 1
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
if __name__ = = "__main__" :
mat = [[ 2 , 0 ],
[ 0 , 2 ]]
res = MaximumHonest(mat)
print (res)
|
Javascript
<script>
function Is_Good(n, index) {
return (n >> index) & 1;
}
function MaximumHonest(mat) {
let N = mat.length;
let ans = 0;
let comb = Math.pow(2, N);
for (let i = 0; i < comb; i++) {
let isValid = true ;
let counter = 0;
for (let person = 0; person < N;
person++) {
if (!Is_Good(i, person))
continue ;
counter++;
for (let 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;
}
let mat = [[2, 0],
[0, 2]];
let res = MaximumHonest(mat);
document.write(res);
</script>
|
C#
using System;
class GFG {
static bool Is_Good( int n, int index)
{
return ((n >> index) & 1) == 1;
}
static int MaximumHonest( int [, ] mat)
{
int N = mat.GetLength(0);
int ans = 0;
int comb = ( int )Math.Pow(2, N);
for ( int i = 0; i < comb; i++) {
bool isValid = true ;
int counter = 0;
for ( int person = 0; person < N; person++) {
if (!Is_Good(i, person))
continue ;
counter++;
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;
}
public static void Main()
{
int [, ] mat = { { 2, 0 }, { 0, 2 } };
int res = MaximumHonest(mat);
Console.Write(res);
}
}
|
Time Complexity: O(2N * N * N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...