1095C - Powers Of Two(二进制)

    xiaoxiao2022-07-07  175

    一些基础的二进制

    #include<bits/stdc++.h> using namespace std; int n ,k , a[105], tot, sum ; int main(){ cin >> n >> k; int x = n; while(x){ a[++tot] = x&1; x>>=1; if(a[tot]) sum++; } while(sum < k){ if(tot == 1) break; a[tot - 1] += 2; a[tot] --; if(!a[tot]) tot--; sum++; } if(sum != k) return puts("NO") , 0; puts("YES"); int t = 1; for(int i = 1; i <= tot ; i++){ for(int j = 1; j <= a[i] ; j ++){ printf("%d ", t); } t <<= 1; } return 0; }

    我开始的思路

    题意:给定一个数,让你用1,2,4,8等2的倍数表示出来,并且要用指定的k个数,输出一种即可。

    思路:他需要的最小的位数为这个数本身转化成2进制数,其中1的数量为最小需要的二进制数,最多需要多少,是n个,因为都可以用1来表示,然后大一位的数代替即可,故可以表示的范围为2进制1的个数到n,这是可以表示出来的,可以从1进行累加到满足,也可以从高位拆分,高位拆分在一般情况下可能更快

    #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cmath> using namespace std; long long int a[505]; int m=0; int tochange(int x) { while(x) { a[m++]=x%2; x/=2; } }//转成2进制 int main() { int n,k; scanf("%d%d",&n,&k); int ans=0; tochange(n); for(int t=m-1; t>=0; t--) { if(a[t]==1) { ans++; } } if(k<ans||k>n) { cout<<"NO"<<endl; }//不满足的情况 else { cout<<"YES"<<endl; if(ans==k) {//如果直接等于就不用拆分了 for(int t=0; t<m; t++) { if(a[t]==1) { long long int s1=pow(2,t); printf("%lld ",s1); } } } else {//从高位拆分,高位-1,低位+2,ans+1 int p=m-1; while(ans!=k) { while(a[p]>=1) { a[p]--; a[p-1]+=2; ans++; if(ans==k) { break; } } p--; }//输出 for(int t=m-1; t>=0; t--) { if(a[t]>=1) { for(int j=0; j<a[t]; j++) { long long int s2=pow(2,t); printf("%lld ",s2); } } } } } return 0; }
    最新回复(0)