HDU - 5920 Ugly Problem(Java大數+貪心)

題目鏈接:點擊查看

題目大意:給出一個非常大的數字 n (\small 10^{1000}),現在要求將其拆分爲數量不超過 50 個的迴文串之和

題目分析:貪心去分就好了,貪心策略如下,奇偶兩種情況:對於奇串 12345:

  1. 選擇前半段 123
  2. 將其減一,變爲 122
  3. 構造迴文串 12221
  4. 用原數字減去當前迴文串然後繼續操作

對於偶串 123456:

  1. 選擇前半段 123
  2. 將其減一,變爲 122
  3. 構造迴文串 122221
  4. 用原數字減去當前迴文串然後繼續操作

這樣就好了,因爲每次選擇了前半段,所以每次數字的長度都會減少一半,那麼 \small 10^{1000} 所需要的操作次數也是 log(1000) 次就夠了

選出的前半段需要減一,是爲了保證構造出來的迴文串一定比原數字要小,如果數字是 321 的話,選出前半段 32 直接構造成 323 的話,會比原數字還要大,但如果減一構造出 313 的話,就能保證一定比原數字要小了

最後當數字小於 20 的時候需要特判一下,不然會陷入死循環

  1. 0 無需處理
  2. 1 ~ 9 保持原數字
  3. 10 拆爲 1 和 9
  4. 11 ~ 20 拆爲 11 + x ,x < 10

剩下的用 java 模擬就好了,因爲需要大數和字符串之間頻繁的轉換,用 C++ 的話會比較繁瑣

代碼:

import java.math.BigInteger;
import java.util.Scanner;

class Main 
{
	static Scanner cin = new Scanner(System.in);
    public static void main(String []args) 
	{
		int kase=cin.nextInt();
		BigInteger _20=BigInteger.valueOf(20);
		for(int t=1;t<=kase;t++)
		{
		    String ans[]=new String[60];
		    int cnt=0;
		    BigInteger n=cin.nextBigInteger();
		    while(n.compareTo(_20)>=1)//n>=20
		    {
		        String res;
		        String s=n.toString();
		        int len=s.length();
		        String s1=s.substring(0,(len+1)/2);
		        BigInteger temp=new BigInteger(s1);
		        temp=temp.subtract(BigInteger.ONE);//減一
		        s1=temp.toString();
		        if((len&1)==0)//偶數串
		        {
		            StringBuffer s2=new StringBuffer(s1);
		            s2.reverse();
		            res=s1+s2.toString();
		        }
		        else//奇數串
		        {
		            StringBuffer s2=new StringBuffer(s1.substring(0,len/2));
		            s2.reverse();
		            res=s1+s2.toString();
		        }
		        ans[++cnt]=res;
		        BigInteger num=new BigInteger(res);
		        n=n.subtract(num);
		    }
		    int num=n.intValue();
		    if(num>=11)//[11,20]
		    {
		        num-=11;
		        ans[++cnt]=String.valueOf(11);
		    }
		    if(num==10)//特判10
		    {
		        num-=9;
		        ans[++cnt]=String.valueOf(9);
		    }
		    if(num!=0)
		    {
		        ans[++cnt]=String.valueOf(num);
		    }
			System.out.printf("Case #%d:\n%d\n",t,cnt);
			for(int i=1;i<=cnt;i++)
			    System.out.println(ans[i]);
		}
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章