ACM ICPC 3252 Round Numbers

來源:互聯網
上載者:User

【序言】剛剛開始學,想找些簡單的題目入手,看到這題AC的人挺多,於是我也來做做這題。

【題目】

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 4732   Accepted: 1607

Description

The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro, Sham, Bo', and a host of other names) in order to make arbitrary decisions such as who gets to be milked first.
They can't even flip a coin because it's so hard to toss using hooves.

They have thus resorted to "round number" matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both "round numbers", the first cow wins,
otherwise the second cow wins.

A positive integer N is said to be a "round number" if the binary representation ofN has as many or more zeroes than it has ones. For example, the integer 9, when written in binary form, is 1001. 1001 has two zeroes and two ones; thus,
9 is a round number. The integer 26 is 11010 in binary; since it has two zeroes and three ones, it is not a round number.

Obviously, it takes cows a while to convert numbers to binary, so the winner takes a while to determine. Bessie wants to cheat and thinks she can do that if she knows how many "round numbers" are in a given range.

Help her by writing a program that tells how many round numbers appear in the inclusive range given by the input (1 ≤Start <Finish ≤ 2,000,000,000).

Input

Line 1: Two space-separated integers, respectively
Start
and Finish.

Output

Line 1: A single integer that is the count of round numbers in the inclusive range Start.. Finish

Sample Input

2 12

Sample Output

6

【思路】

1.首先的想法,就是輸入一個數字n,能否令f(n)為那些≤n的"round numbers"的個數?那麼題目就可以轉化為f(Finish)-f(Start-1).

2.那麼如何求這個f(n)?

           1)在求這個f(n)之前,先將n的二進位運算式求出來:(an)(an-1)...(a1)(a0). 當然這個an=1 (第一位是為1的)。後面以n=11,001,001為例做闡述(這是一個8位元)。

           2)個人希望分別找出a)<10,000,000、b)10,000,000~11,000,000、c)11,000,000~11,001,000、d)11,001,000~11,001,001、e)10,101,001之間(左開右閉)的"round numbers"數,那問題不就迎刃而解了嗎?!

           3)而a)可以對應成一個7位的“0”“1”串X,XXX,XXX,每一位上任意取0或者1,滿足count("0") >= count("1")的字串的個數.這個為C(7,0)+C(7,1)+...+C(7,3).

這裡稍作修改,a)對應成7位+首位是1的字串;6位+首位是1的字串;……;

                  b)可以對應成一個6位的“0”“1”串10,000,000+XXX,XXX,每一位上任意取0或者1,滿足count("0") +1>= count("1")+1(前2位是10)的字串的個數.這個為C(6,0)+C(6,1)+...+C(6,3).

                 c)d)類似,e)最後一位的情況特殊處理.

           4)於是需要一個函數用於解決這樣的問題:一個k位的“0”“1”串XX...X,每一位上任意取0或者1,滿足count("0")+ZeroNum >= count("1")+OneNum的字串的個數。

於是定義一個函數用於解決這樣的問題。

int tempFunction(int k, int ZeroNum, int OneNum){int temp = ((k+ZeroNum+1-OneNum)%2 == 0) ? ((k+ZeroNum+1-OneNum)/2) : ((k+ZeroNum-OneNum)/2+1);//set the upper bound for count("1")//return C(k,0)+C(k,1)+...+C(k,temp-1)int sum = 0;if (temp <= 0){return 0;}for (int i = 0; i < temp; ++i){//楊輝三角的值已計算sum = sum + YangHuiTriangle[(k-1)*k/2+i-1];}return sum;}

 

其中楊輝三角的值可以用遞推公式計算

void InitialYangHuiTriangle(int *TriangleArray, int n)//n是組合數的一個參數,對應楊輝三角的時候,行數多1.{for (int i = 1; i <= n+1; ++i){for (int j = 1; j <= i; ++j){if ((j == 1) || (j == i) || (i == 1)){TriangleArray[(i-1)*i/2+j-1] = 1;}else{TriangleArray[(i-1)*i/2+j-1] = TriangleArray[(i-2)*(i-1)/2+j-2] + TriangleArray[(i-2)*(i-1)/2+j-1];}}}}

綜合以上的敘述,得到的如下程式:

【程式】

#include<iostream>using namespace std;int YangHuiTriangle[(1+25)*25/2];int SummateArray(int Array[], int n);void InitialYangHuiTriangle(int *TriangleArray, int n);int tempFunction(int, int, int);int RoundNumber(int);int main(){int StartNum;int FinishNum;cin >> StartNum  >> FinishNum;InitialYangHuiTriangle(YangHuiTriangle, 24);cout << RoundNumber(FinishNum)-RoundNumber(StartNum-1)<<endl;return 0;}/******************************************************************************int RoundNumber(int aNumber)*函數作用:函數用來計算小於等於aNumber的"round number"的個數*函數輸入:十進位整數aNumber (0 <= aNumber <= 20,000,000)*函數輸出:小於等於aNumber的"round number"的個數*函數備忘:暫無*****************************************************************************/int RoundNumber(int aNumber){int countNumber = 0;if ((aNumber == 0)||(aNumber == 1)){return 0;}int BinaryNumber[24];int location = 0;while (aNumber != 1){BinaryNumber[location] = aNumber%2;location = location + 1;aNumber = aNumber/2;}BinaryNumber[location] = 1;//這樣就將十進位整數轉化為二進位表現形式,倒敘放在數組BinaryNumber[24]中//接下來是判斷1的位置int tempFirst1=location-1;while(tempFirst1 > 0){countNumber += tempFunction(tempFirst1,0,1);--tempFirst1;}int next = location - 1;//已經知道了location(>=1)對應的位置是1了,用next 用以記錄下一個1的位置int pre = location;while (next >= 0){if(next == 0)//此時表明這是最後一位{if(BinaryNumber[next] == 1)//此時pre的位置為1,next的位置也為1{countNumber += tempFunction(next, pre-next, 1);next -= 1;}else//表明這個數就是aNumber的二進位運算式,只需要驗證該數是否為round number 即可{if (2*SummateArray(BinaryNumber, location+1) <= (location + 1)){countNumber += 1;}next -= 1;}}else{if(BinaryNumber[next] == 1)//此時pre的位置為1,next的位置也為1{countNumber += tempFunction(next, pre-next, 1);pre = next;next -= 1;}else{next -= 1;}}}return countNumber;}int tempFunction(int k, int ZeroNum, int OneNum){if ( k==0 ){return 0;}int temp = ((k+ZeroNum+1-OneNum)%2 == 0) ? ((k+ZeroNum+1-OneNum)/2) : ((k+ZeroNum-OneNum)/2+1);//set the upper bound for count("1")//return C(k,0)+C(k,1)+...+C(k,temp-1)int sum = 0;if (temp <= 0){return 0;}for (int i = 0; i < temp; ++i){//楊輝三角的值已計算sum = sum + YangHuiTriangle[k*(k+1)/2+i];}return sum;}void InitialYangHuiTriangle(int *TriangleArray, int n)//n是組合數的一個參數,對應楊輝三角的時候,行數多1.{for (int i = 1; i <= n+1; ++i){for (int j = 1; j <= i; ++j){if ((j == 1) || (j == i) || (i == 1)){TriangleArray[(i-1)*i/2+j-1] = 1;}else{TriangleArray[(i-1)*i/2+j-1] = TriangleArray[(i-2)*(i-1)/2+j-2] + TriangleArray[(i-2)*(i-1)/2+j-1];}}}}/******************************************************************************int SummateArray(int Array[], int n)*函數作用:函數用來計算數組的所有元素的和*函數輸入:長度為n的數組Array*函數輸出:數組元素的和*函數備忘:暫無*****************************************************************************/int SummateArray(int Array[], int n){int sum = 0;for (int i = 0; i < n; ++i){sum = sum + Array[i];}return sum;}

【結果】 Runtime Error

 

【修改】 待續

這是從網上搜尋來的,發現思路類似,但是本人的比較拙劣

#include<iostream>using namespace std;int C[33][33];int MAX[33];int B[33];int tobinary(int b){int i=1;while(b) {  B[i++]=b%2; b/=2;} return i-1;}void init(){ int i,j;C[1][0]=C[1][1]=1;for(i=2;i<=32;i++){ C[i][0]=1; for(j=1;j<=i;j++) C[i][j]=C[i-1][j]+C[i-1][j-1]; }MAX[1]=0; for(i=2;i<=32;i++) {for(j=(i+1)/2;j<i;j++) MAX[i]+=C[i-1][j]; }}int howmany(int n,int k,int *p) {if(k>=n||k<0) return 0; if((n==1&&k==0)||(n==2&&k==1)) return 1; if(p[n-1]==0) return howmany(n-1,k-1,p);elsereturn C[n-2][k-1]+howmany(n-1,k,p);}int compute(int n){int i,ans=0;int len=tobinary(n);for(i=(len+1)/2;i<len;i++)ans+=howmany(len,i,B);for(i=1;i<len;i++)ans+=MAX[i];return ans;}int main(){ init(); int start,finish;cin >> start >> finish; cout<<compute(finish)-compute(start-1)<<endl;return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.