更改位以生成特定的或值

给定两个正整数A和B,我们最多可以改变两个数中的K位,使其等于给定的目标数T。在多个解的情况下,尽量保持A尽可能小。

null

例如:

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.

我们可以通过迭代A和B的所有位并贪婪地改变它们来解决这个问题,

  • 如果目标T的第i位为0,则将A和B的第i位设置为0(如果尚未设置)
  • 如果目标T的第i位是1,那么我们将尝试将其中一位设置为1,并将B的第i位仅更改为1(如果尚未更改),以最小化A。

完成上述程序后,如果 更改的位不止是K ,则不可能通过最多改变K位来获得A和B作为T的或。 如果 更改的位小于k ,然后我们可以通过使用K的剩余值来进一步最小化A的值,对于K,我们将再次循环位,如果在任何时候,

  • i-th A位为1,i-th B位为0,然后我们将进行2次更改,并将两者翻转。
  • i-th A和B位为1,然后我们再次进行1更改并翻转A位。

上述解决方案的总时间复杂度为O(最大位数)。

C++

// 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" ;
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;
}


PHP

<?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" ;
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 , "" ;
}
// Driver Code
$A = 175;
$B = 66;
$K = 5;
$T = 100;
minChangeToReachTaregetOR( $A , $B , $K , $T );
// This code is contributed by ajit
?>


输出:

36 64

本文由 乌特卡什·特里维迪 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 贡献极客。组织 或者把你的文章寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享