按鈕問題

題目

現有兩個按鈕,按下按鈕0會執行2x+1,按下1執行2x+2。x初值爲0,現要求出任意正整數n應使用何種按法使得x能變成n。

遍歷

打眼一看這題就是遍歷啊,找所有解法,但是不同於別的簡單題,需要你有一個順序去遍歷。遞歸唄。使用深度優先搜索。
具體如下。

#include<stdio.h>
#include<stdlib.h>
int success;

int max(int s){
    int n = 0;
    int t = 0;
    while(t<s){
        t = t*2+1;
        n++;
    }
    return n;
}

void print(int arr[],int now){
    int i;
    for(i = 0;i<now;i++){
        printf("%d ",arr[i]);
    }
    puts("");
}

void do_sth(int arr[],int now,int t,int m,int type){

    //arr[]保存路徑的數組
    //now 當前步數
    //t當前結果
    //m目標值
    //type 當前算法
    if(success == 1){
        return ;
    }
    if(t > m){
        return;
    }

    arr[now] = type;
    int new_t;
    if(type==0){
        new_t = t*2 + 1;

    }else{
        new_t = t*2 + 2;
    }
    if(new_t == m){
        success = 1;
        print(arr,now+1);
        return;
    }else{
        do_sth(arr,now+1,new_t,m,0);
        do_sth(arr,now+1,new_t,m,1);
    }
}

int main(void){
    success = 0;
    int n;
    int t;
    int *arr;
    while(scanf("%d",&n) != EOF){
        success = 0;
        t = max(n);
        arr = malloc(sizeof(int)*t);
        do_sth(arr,0,0,n,0);
        do_sth(arr,0,0,n,1);
                free(arr);
    }
}

逆向求解

因爲這道題每個要求解的數的答案都是固定的,dfs遍歷太耗費時間。實際可以通過以下方法求解。
1. n大於0嗎?是——>2。否——>逆序輸出結果
2. n是奇數嗎?是——>3。否——>4
3. n=(n-1)/2 記錄按鈕0 ——>1
4. n=(n-2)/2 記錄按鈕1 ——>1
python代碼

#! /usr/bin/env python3

def solve(n):
    s = []
    while(n>0):
        if(n % 2 == 1):
            n = (n-1)/2
            s.append(0)
        else:
            n = (n-2)/2
            s.append(1)

    for i in s:
        print('{} '.format(i),end='')
    print("")

try:
    while True:
        s = int(input())
        solve(s)

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