(二進位制貪心)ZOJ - 3987 Numbers
阿新 • • 發佈:2018-11-11
題意 :將值為 n 的數分解成 m 個數的和,並且使這 m 個數的 or 值最小。
題解 :見程式碼
import java.math.*; import java.util.*; public class Main{ public static void main(String[] args) { // TODO Auto-generated method stub Scanner in=new Scanner(System.in); BigInteger base[]=new BigInteger[5000]; BigInteger two=new BigInteger("2"); base[0]=BigInteger.ONE; for(int i=1;i<5000;i++) base[i]=base[i-1].multiply(two); while(in.hasNext()){ int t=in.nextInt(); while(t>0){ BigInteger n=in.nextBigInteger(); BigInteger m=in.nextBigInteger(); BigInteger sum=BigInteger.ZERO; int up=0; // up 二進位制位數的最高位 for(int i=0;i<5000&&sum.compareTo(n)<0;i++){ sum=sum.add(m.multiply(base[i])); up=i; } BigInteger nn=n,ans=BigInteger.ZERO; for(int i=up;i>=0;i--){ BigInteger s=base[i].subtract(BigInteger.ONE); // 假如 第 i 位不取 if(s.multiply(m).compareTo(nn)>=0) continue; // 不取第 i 位可以 // 不取第 i 位不可以 BigInteger k=nn.divide(base[i]); k=k.min(m); // 儘可能多的填充 nn=nn.subtract(k.multiply(base[i])); ans=ans.add(base[i]); } System.out.println(ans); t--; } } } }