An Easy Problem(模擬 C++)

An Easy Problem
Total time limit: 1000 ms memory limit: 65536 kb
describe
As we known, data stored in the computers is in binary form. The problem we discuss now is about the positive integers and its binary form.
Given a positive integer I, you task is to find out an integer J, which is the minimum integer greater than I, and the number of ‘1’s in whose binary form is the same as that in the binary form of I.
For example, if “78” is given, we can write out its binary form, “1001110”. This binary form has 4 ‘1’s. The minimum integer, which is greater than “1001110” and also contains 4 ‘1’s, is “1010011”, i.e. “83”, so you should output “83”.
input
One integer per line, which is I (1 <= I <= 1000000).
A line containing a number “0” terminates input, and this line need not be processed.
output
One integer per line, which is J.
Sample input

1
2
3
4
78
0

Sample output

2
4
5
8
83

source
POJ Monthly,zby03

翻譯:
一個簡單的問題
總時間限制: 1000毫秒內存限制: 65536 kb
描述
衆所周知,存儲在計算機中的數據是二進制的。我們現在討論的問題是正整數及其二進制形式。給定正整數I,你的任務是找出一個整數J,它是大於I的最小整數,以及二進制形式與I的二進制形式相同的“1”的數量例如,如果給出“78”,我們可以寫出它的二進制形式“1001110”。這個二進制形式有4 ’ 1。大於“1001110”並且也包含4 ’ 1”的最小整數是“1010011”,即“83”,所以你應該輸出“83”。
輸入
每行一個整數,即I ( 1 < = I < = 100000 )。包含數字“0”的行終止輸入,無需處理該行。
輸出
每行一個整數,即j

思路點拔:確實是一個簡單的問題,本題最核心的操作就是:如何統計這個數的二進制表示時出現的1的次數,所以,這個需要手寫一個函數實現,轉化思想就是輾轉相除,然後將餘數倒着存放就是這個數的二進制數,這樣可能很抽象,我們來舉個例子吧,比如說用8來舉例:
2|8 0
2|4 0
2|2 0
2|1 1
2|0 0
所以8的二進制就是01000,由於本題是求1的出現次數,所以前導0也不重要,同樣,正序與反序也不重要,所以這個函數就好寫了,就是模擬上述的短除過程

int two(int x)
{
    int tot=0; //tot統計出現1的次數
    while(x>0) //模擬短除過程
    {
        if(x%2==1) //如果出現了1
            tot++; //就累加
        x/=2; 
    }
    return tot; //返回tot就是1的出現次數
}

相信這個函數出來後,後面的工作就簡單了,但是這個題是說大於這個數的數的二進制表示法中1出現的次數相等,就用一個一重循環就能搞定,你可以這樣寫
for(int i=n+1;;i++)就是不要上限,但是如果找到了符合要求的數之後,就馬上輸出並結束
同樣,你也可以這樣寫:
for(int i=n+1;i<=100000;i++)就是本題的上限,也是可以的,兩種方法的時間都是一樣的
都說到這個份上了,我覺得差不多上代碼了

#include<cstdio>
int two(int x) //統計1出現的次數
{
    int tot=0;
    while(x>0) //模擬短除法
    {
        if(x%2==1) //統計1出現的次數
            tot++;
        x/=2;
    }
    return tot; //返回1出現的次數
}
int main()
{
    int m;
    while(scanf("%d",&m)) //無限輸入
    {
        if(m==0) return 0; //輸入結束的指令
        else
        {
            int a=m+1;
            while(a>m) //枚舉所有大於m的數
            {
                if(two(a)==two(m)) //如果出現1的次數相同
                {
                    printf("%d\n",a); //直接輸出並結束
                    break;
                }
                else //否則就繼續找
                {
                    a++;
                }
            }
        }
    }
    return 0;
}
//保證不會超時^_^
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章