A. Access problem

Any positive integers n and k (1≤n≤1,000,000, 0≤k≤n) are given, and the numbering rules are as follows:
For example, n=16, k=4, the
first time the number 1 is taken, the remainder after the number is 16-1 =15 the
second fetch 2 the remainder after fetch is 15-2=13 the
third fetch 4 the remainder after fetch is 13-4=9 the
fourth fetch 8 the remainder after fetch is 9- 8=1
When the fifth time is taken, because the remainder is 1, it is not enough to take, then the
remainder is 1+k=5, and then the
fifth time is taken from 1 and the remainder is 5- 1=4
Take the number 2 for the sixth time. The remainder after taking the number is 4-2=2.
Since the number 4 is taken for the seventh time, but the remainder is 2, we have to add k again, 2+4=6, and then take 1
The seventh time to take the number 1 The remainder after the number is 6-1=5 The
eighth time to take the 2 The remainder after the number is 5-2=3 The
ninth time to take 4 but not enough to take
3+4=7 The
ninth The number of times access is 1 The remainder after the number is 7-1=6 The remainder after the number is
accessed 2 The remainder after the number is 6-2=4 The
eleventh time is 4 The remainder after the number is 4-4=0 Just take it out.
It can be seen that when n=16 and k=4, take it 11 times according to the above method.

Input
two positive integers of type int, n and k.


If the output is just taken out, the output will be taken out of the required number of times according to the access rules. If it can never be completed, output "Bad Number!".

Samples
Input Copy
16 4
Output
11

Question: Give you n and m, and ask you to subtract 2 0 ,2 1 ,2 2 ,... until (2 x >n) if n is zero, output the number of subtractions, and add it if it is not zero. continuing with the above from two m 0 begin to reduce until n is 0, so that if not n = 0, then the output "Bad Number!".


Idea: First, it is subtracted according to 2 i . If n is greater than 2 i , it must be n-2 i . If n is less than 2 i , then m must be added. Then we can know that the current n must be less than The original n/2, because the original i want to add in front of i is exactly 2 i-1 -1 , then we only need to enumerate n/2+m so many times to add m to know whether he will enter an infinite loop , Or if you need the remainder of n to appear, you can directly determine that he has entered an endless loop. But you have to mark the remainder each time. This is not marked.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[50];

int main() {
    a[0]=1;
    for(int i=1; i<=31; i++) {
        a[i]=a[i-1]*2;
    }
    ll n,m;
    cin>>n>>m;
    ll ans=0;
    ll sum=n;
    for(int i=0; i<=n/2+m; i++,sum+=m) {
        for(int j=0; j<=31; j++) {
            if(a[j]<=sum) {
                sum-=a[j];
                ans++;
            } else break;
        }
        if(!sum) break;
    }
    if(sum) cout<<"Bad Number!"<<endl;
    else cout<<ans<<endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45911397/article/details/114334530