Given two positive integers A and B, we can change at most K bits in both the numbers to make OR of them equal to a given target number T. In the case of multiple solutions try to keep A as small as possible. Examples :
Input : A = 175, B = 66, T = 100, K = 5 Output : A = 36 B = 64 Initial bits of A = 1010 1111 Changed bits of A = 0010 0100 Initial bits of B = 0100 0010 Changed bits of B = 0100 0000 OR of changed Bits = 0110 0100 Which has decimal value equal to Target T. Input : A = 175, B = 66, T = 100, K = 4 Output : Not Possible It is not possible to get OR of A and B as T, just by changing K bits.
We can solve this problem by iterating over all bits of A and B and greedily changing them that is,
- If i-th bit of Target T is 0 then set i-th bits of A and B to 0 (if not already)
- If i-th bit of Target T is 1 then we will try to set one of the bits to 1 and we will change i-th bit of B only to 1(if not already) to minimize A.
After above procedure, if changed bits are more than K, then it is not possible to get OR of A and B as T by changing at most K bits. If changed bits are less than k, then we can further minimize the value of A by using remaining value of K for which we will loop over bits one more time and if at any time,
- i-th A bit is 1 and i-th B bit is 0 then we will make 2 changes and flip both.
- i-th A and B bits are 1 then again we will make 1 change and flip A’s bit.
Total time complexity of above solution will be O(max number of bits).
// C++ program to change least bits to // get desired OR value #include <bits/stdc++.h> using namespace std;
// Returns max of three numbers int max( int a, int b, int c)
{ return max(a, max(b, c));
} // Returns count of bits in N int bitCount( int N)
{ int cnt = 0;
while (N)
{
cnt++;
N >>= 1;
}
return cnt;
} // Returns bit at 'pos' position bool at_position( int num, int pos)
{ bool bit = num & (1<<pos);
return bit;
} // Utility method to toggle bit at // 'pos' position void toggle( int &num, int pos)
{ num ^= (1 << pos);
} // method returns minimum number of bit flip // to get T as OR value of A and B void minChangeToReachTaregetOR( int A, int B,
int K, int T)
{ int maxlen = max(bitCount(A), bitCount(B),
bitCount(T));
// Loop over maximum number of bits among
// A, B and T
for ( int i = maxlen - 1; i >= 0; i--)
{
bool bitA = at_position(A, i);
bool bitB = at_position(B, i);
bool bitT = at_position(T, i);
// T's bit is set, try to toggle bit
// of B, if not already
if (bitT)
{
if (!bitA && !bitB)
{
toggle(B, i);
K--;
}
}
else
{
// if A's bit is set, flip that
if (bitA)
{
toggle(A, i);
K--;
}
// if B's bit is set, flip that
if (bitB)
{
toggle(B, i);
K--;
}
}
}
// if K is less than 0 then we can make A|B == T
if (K < 0)
{
cout << "Not possible\n" ;
return ;
}
// Loop over bits one more time to minimise
// A further
for ( int i = maxlen - 1; K > 0 && i >= 0; --i)
{
bool bitA = at_position(A, i);
bool bitB = at_position(B, i);
bool bitT = at_position(T, i);
if (bitT)
{
// If both bit are set, then Unset
// A's bit to minimise it
if (bitA && bitB)
{
toggle(A, i);
K--;
}
}
// If A's bit is 1 and B's bit is 0,
// toggle both
if (bitA && !bitB && K >= 2)
{
toggle(A, i);
toggle(B, i);
K -= 2;
}
}
// Output changed value of A and B
cout << A << " " << B << endl;
} // Driver code int main()
{ int A = 175, B = 66, K = 5, T = 100;
minChangeToReachTaregetOR(A, B, K, T);
return 0;
} |
// Java program to change least bits to // get desired OR value class GFG {
// Returns max of three numbers
static int max( int a, int b, int c)
{
return Math.max(a, Math.max(b, c));
}
// Returns count of bits in N
static int bitCount( int N)
{
int cnt = 0 ;
while (N != 0 )
{
cnt++;
N >>= 1 ;
}
return cnt;
}
// Returns bit at 'pos' position
static int at_position( int num, int pos)
{
int bit = num & ( 1 <<pos);
return bit;
}
// Utility method to toggle bit at
// 'pos' position
static int toggle( int num, int pos)
{
num ^= ( 1 << pos);
return num;
}
// method returns minimum number of bit flip
// to get T as OR value of A and B
static void minChangeToReachTaregetOR( int A, int B,
int K, int T)
{
int maxlen = max(bitCount(A), bitCount(B),
bitCount(T));
// Loop over maximum number of bits among
// A, B and T
for ( int i = maxlen - 1 ; i >= 0 ; i--)
{
int bitA = at_position(A, i);
int bitB = at_position(B, i);
int bitT = at_position(T, i);
// T's bit is set, try to toggle bit
// of B, if not already
if (bitT != 0 )
{
if ((bitA == 0 ) && (bitB == 0 ))
{
B = toggle(B, i);
K--;
}
}
else
{
// if A's bit is set, flip that
if (bitA != 0 )
{
A = toggle(A, i);
K--;
}
// if B's bit is set, flip that
if (bitB != 0 )
{
B = toggle(B, i);
K--;
}
}
}
// if K is less than 0 then we can make A|B == T
if (K < 0 )
{
System.out.println( "Not possible" );
return ;
}
// Loop over bits one more time to minimise
// A further
for ( int i = maxlen - 1 ; K > 0 && i >= 0 ; --i)
{
int bitA = at_position(A, i);
int bitB = at_position(B, i);
int bitT = at_position(T, i);
if (bitT != 0 )
{
// If both bit are set, then Unset
// A's bit to minimise it
if ((bitA != 0 ) && (bitB != 0 ))
{
toggle(A, i);
K--;
}
}
// If A's bit is 1 and B's bit is 0,
// toggle both
if ((bitA != 0 ) && (bitB == 0 ) && K >= 2 )
{
toggle(A, i);
toggle(B, i);
K -= 2 ;
}
}
// Output changed value of A and B
System.out.println(A + " " + B);
}
//Driver Code
public static void main(String[] args) {
int A = 175 , B = 66 , K = 5 , T = 100 ;
minChangeToReachTaregetOR(A, B, K, T);
}
} //This code is contributed by phasing17 |
# Python3 program to change least bits to # get desired OR value # Returns count of bits in N def bitCount(N):
cnt = 0 ;
while (N > 0 ):
cnt + = 1
N >> = 1
return cnt
# Returns bit at 'pos' position def at_position(num, pos):
bit = num & ( 1 <<pos)
return (bit ! = 0 )
# Utility method to toggle bit at # 'pos' position def toggle(num, pos):
num ^ = ( 1 << pos)
return num
# method returns minimum number of bit flip # to get T as OR value of A and B def minChangeToReachTaregetOR(A, B, K, T):
maxlen = max (bitCount(A), bitCount(B), bitCount(T));
# Loop over maximum number of bits among
# A, B and T
for i in range (maxlen - 1 , - 1 , - 1 ):
bitA = at_position(A, i);
bitB = at_position(B, i);
bitT = at_position(T, i);
# T's bit is set, try to toggle bit
# of B, if not already
if (bitT > 0 ):
if (( not bitA) and ( not bitB)):
B = toggle(B, i)
K - = 1
else :
# if A's bit is set, flip that
if (bitA > 0 ):
A = toggle(A, i)
K - = 1
# if B's bit is set, flip that
if (bitB > 0 ):
B = toggle(B, i)
K - = 1
# if K is less than 0 then we can make A|B == T
if (K < 0 ):
print ( "Not possible" );
return ;
# Loop over bits one more time to minimise
# A further
i = maxlen - 1
while True :
if K < 0 or i < 0 :
break
bitA = at_position(A, i);
bitB = at_position(B, i);
bitT = at_position(T, i);
if (bitT > 0 ):
# If both bit are set, then Unset
# A's bit to minimise it
if (bitA and bitB):
A = toggle(A, i)
K - = 1
# If A's bit is 1 and B's bit is 0,
# toggle both
if ((bitA ! = 0 ) and ( not bitB) and K > = 2 ):
A = toggle(A, i)
B = toggle(B, i)
K - = 2
i - = 1
# Output changed value of A and B
print (A, B)
# Driver code A = 175
B = 66
K = 5
T = 100
minChangeToReachTaregetOR(A, B, K, T) # This code is contributed by phasing17 |
// C# program to change least bits to // get desired OR value using System;
class GFG {
// Returns max of three numbers
static int max( int a, int b, int c)
{
return Math.Max(a, Math.Max(b, c));
}
// Returns count of bits in N
static int bitCount( int N)
{
int cnt = 0;
while (N != 0) {
cnt++;
N >>= 1;
}
return cnt;
}
// Returns bit at 'pos' position
static int at_position( int num, int pos)
{
int bit = num & (1 << pos);
return bit;
}
// Utility method to toggle bit at
// 'pos' position
static int toggle( int num, int pos)
{
num ^= (1 << pos);
return num;
}
// method returns minimum number of bit flip
// to get T as OR value of A and B
static void minChangeToReachTaregetOR( int A, int B,
int K, int T)
{
int maxlen
= max(bitCount(A), bitCount(B), bitCount(T));
// Loop over maximum number of bits among
// A, B and T
for ( int i = maxlen - 1; i >= 0; i--) {
int bitA = at_position(A, i);
int bitB = at_position(B, i);
int bitT = at_position(T, i);
// T's bit is set, try to toggle bit
// of B, if not already
if (bitT != 0) {
if ((bitA == 0) && (bitB == 0)) {
B = toggle(B, i);
K--;
}
}
else {
// if A's bit is set, flip that
if (bitA != 0) {
A = toggle(A, i);
K--;
}
// if B's bit is set, flip that
if (bitB != 0) {
B = toggle(B, i);
K--;
}
}
}
// if K is less than 0 then we can make A|B == T
if (K < 0) {
Console.WriteLine( "Not possible" );
return ;
}
// Loop over bits one more time to minimise
// A further
for ( int i = maxlen - 1; K > 0 && i >= 0; --i) {
int bitA = at_position(A, i);
int bitB = at_position(B, i);
int bitT = at_position(T, i);
if (bitT != 0) {
// If both bit are set, then Unset
// A's bit to minimise it
if ((bitA != 0) && (bitB != 0)) {
toggle(A, i);
K--;
}
}
// If A's bit is 1 and B's bit is 0,
// toggle both
if ((bitA != 0) && (bitB == 0) && K >= 2) {
toggle(A, i);
toggle(B, i);
K -= 2;
}
}
// Output changed value of A and B
Console.WriteLine(A + " " + B);
}
// Driver Code
public static void Main( string [] args)
{
int A = 175, B = 66, K = 5, T = 100;
minChangeToReachTaregetOR(A, B, K, T);
}
} // This code is contributed by phasing17 |
<?php // PHP program to change least // bits to get desired OR value // Returns max of three numbers function maxDD( $a , $b , $c )
{ return max( $a , (max( $b , $c )));
} // Returns count of bits in N function bitCount( $N )
{ $cnt = 0;
while ( $N )
{
$cnt ++;
$N >>= 1;
}
return $cnt ;
} // Returns bit at 'pos' position function at_position( $num , $pos )
{ $bit = $num & (1 << $pos );
return $bit ;
} // Utility method to toggle // bit at 'pos' position function toggle(& $num , $pos )
{ $num ^= (1 << $pos );
} // method returns minimum // number of bit flip to // get T as OR value of A and B function minChangeToReachTaregetOR( $A , $B ,
$K , $T )
{ $maxlen = max(bitCount( $A ),
bitCount( $B ),
bitCount( $T ));
// Loop over maximum number
// of bits among A, B and T
for ( $i = $maxlen - 1; $i >= 0; $i --)
{
$bitA = at_position( $A , $i );
$bitB = at_position( $B , $i );
$bitT = at_position( $T , $i );
// T's bit is set, try to toggle
// bit of B, if not already
if ( $bitT )
{
if (! $bitA && ! $bitB )
{
toggle( $B , $i );
$K --;
}
}
else
{
// if A's bit is set,
// flip that
if ( $bitA )
{
toggle( $A , $i );
$K --;
}
// if B's bit is set,
// flip that
if ( $bitB )
{
toggle( $B , $i );
$K --;
}
}
}
// if K is less than 0 then
// we can make A|B == T
if ( $K < 0)
{
echo "Not possible\n" ;
return ;
}
// Loop over bits one more
// time to minimise A further
for ( $i = $maxlen - 1;
$K > 0 && $i >= 0; -- $i )
{
$bitA = at_position( $A , $i );
$bitB = at_position( $B , $i );
$bitT = at_position( $T , $i );
if ( $bitT )
{
// If both bit are set, then
// Unset A's bit to minimise it
if ( $bitA && $bitB )
{
toggle( $A , $i );
$K --;
}
}
// If A's bit is 1 and B's
// bit is 0, toggle both
if ( $bitA && ! $bitB && $K >= 2)
{
toggle( $A , $i );
toggle( $B , $i );
$K -= 2;
}
}
// Output changed value
// of A and B
echo $A , " " , $B , "\n" ;
} // Driver Code $A = 175;
$B = 66;
$K = 5;
$T = 100;
minChangeToReachTaregetOR( $A , $B , $K , $T );
// This code is contributed by ajit ?> |
// JavaScript program to change least bits to // get desired OR value // Returns max of three numbers function max(a, b, c)
{ return Math.max(a, Math.max(b, c));
} // Returns count of bits in N function bitCount(N)
{ let cnt = 0;
while (N > 0)
{
cnt++;
N >>= 1;
}
return cnt;
} // Returns bit at 'pos' position function at_position(num, pos)
{ let bit = num & (1<<pos);
return (bit != 0) ? true : false ;
} // Utility method to toggle bit at // 'pos' position function toggle(num, pos)
{ num ^= (1 << pos);
return num;
} // method returns minimum number of bit flip // to get T as OR value of A and B function minChangeToReachTaregetOR(A, B, K, T)
{ let maxlen = Math.max(bitCount(A), bitCount(B),
bitCount(T));
// Loop over maximum number of bits among
// A, B and T
for (let i = maxlen - 1; i >= 0; i--)
{
let bitA = at_position(A, i);
let bitB = at_position(B, i);
let bitT = at_position(T, i);
// T's bit is set, try to toggle bit
// of B, if not already
if (bitT )
{
if ((!bitA) && (!bitB))
{
B = toggle(B, i);
K--;
}
}
else
{
// if A's bit is set, flip that
if (bitA)
{
A = toggle(A, i);
K--;
}
// if B's bit is set, flip that
if (bitB)
{
B = toggle(B, i);
K--;
}
}
}
// if K is less than 0 then we can make A|B == T
if (K < 0)
{
console.log( "Not possible" );
return ;
}
// Loop over bits one more time to minimise
// A further
for (let i = maxlen - 1; K > 0 && i >= 0; --i)
{
let bitA = at_position(A, i);
let bitB = at_position(B, i);
let bitT = at_position(T, i);
if (bitT)
{
// If both bit are set, then Unset
// A's bit to minimise it
if (bitA && bitB)
{
A = toggle(A, i);
K--;
}
}
// If A's bit is 1 and B's bit is 0,
// toggle both
if (bitA && !bitB && K >= 2)
{
A = toggle(A, i);
B = toggle(B, i);
K -= 2;
}
}
// Output changed value of A and B
console.log(A, B);
} // Driver code let A = 175, B = 66, K = 5, T = 100; minChangeToReachTaregetOR(A, B, K, T); //This code is contributed by phasing17 |
Output :
36 64
Time Complexity: O(log(max({A, B, T})))
Auxiliary Space: O(1)