ZOJ 3987 秦皇岛现场赛G题 java

题目连接:ZOJ 3987

原网页含有mathtype公式,复制过来会乱,所以这里就不放题了。

题意:给2个大数n和m,要求把n分成m个数相加,并且取或运算后最小。

题目分析:

首先考虑将n平分m份,如果恰好可以平分即n%m==0,则答案就是n/m。

之后考虑无法平分的情况,n/m+1会产生二进制的进位,如n=15,m=4的情况,n/m=3,n/m+1=4,产生了进位。考虑n/m+1用二进制表示,取其lowbit,比如n=32,m=6,

则n/m+1=6=110,其lowbit就是把最右边的1变为0,lowbit(6)=4;此时这m个数是一定会加上4的,剩下的再重复上述步骤,知道剩下的数小于m。如果n/m+1是2的次方数,lowbit数不变,此时这个数也是一定要取的,不过只能尽量多的取,如上述n=15,m=4的情况,前三个每个取4,后一个不取。

最后考虑n=32,m=6的情况:第一步n/m+1=6,取4,剩余32-6*4=8,8/6+1=2,则前3个数+2,后面3个数不变,剩下0,结束。

lowbit就是x&(-x)。

由于这里需要大数取模,相减,以及与运算,所以在没有详尽的大数模板情况下java是个不错的选择。

import java.io.*;
import java.util.*;
import java.math.*;
public class Main {
	public static void main(String[] args)
	{
		int T;
		BigInteger m,n,div,left,l;
		BigInteger []t=new BigInteger[1111];
		Scanner cin=new Scanner(System.in);
		T=cin.nextInt();
		for(int kase=0;kase<T;kase++)
		{
			n=cin.nextBigInteger();
			m=cin.nextBigInteger();
			div=n.divide(m);
			if(n.equals(m.multiply(div)))
			{
				System.out.println(div);
				continue;
			}
			BigInteger ans=BigInteger.valueOf(0);
			left=n;
			div=div.add(BigInteger.valueOf(1));
			while(left.compareTo(BigInteger.ZERO)==1)
			{
				BigInteger bit=lowbit(div);
				if(bit.equals(div))
				{
					ans=ans.add(div);
					BigInteger buf=left.divide(div);
					buf=buf.multiply(div);
					left=left.subtract(buf);
					div=left.divide(m);
					div=div.add(BigInteger.valueOf(1));
				}
				else
				{
					BigInteger buf=div.subtract(bit);
					ans=ans.add(buf);
					buf=buf.multiply(m);
					left=left.subtract(buf);
					div=left.divide(m);
					div=div.add(BigInteger.valueOf(1));
				}
			}
			System.out.println(ans);
		}
	}

	private static BigInteger lowbit(BigInteger div) {
		return div.and(div.multiply(BigInteger.valueOf(-1)));
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值