Descripción del Título
Como programador, al Sr. Zhao realmente le gusta
tanto el sistema binario que le gustan tanto las potencias de 2.
Quiere que le ayudes a averiguar si el entero positivo n se puede dividir en k sumas de potencias de 2
Ingresa
primero La fila tiene solo dos enteros positivos n, k (1 ≤ n ≤ 10 ^ 9, 1 ≤ k ≤ 2 · 10 ^ 5).
Salida
Si no existe tal esquema, salida NO.
De lo contrario, la salida SÍ y la salida k enteros positivos, su suma es n, si hay múltiples esquemas, la salida cualquiera.
Ejemplos
Entrada
9 4
Salida
SÍ
1 2 2 4
Entrada
8 1
Salida
SÍ
8
Entrada
5 1
Salida
NO
Entrada
3 7
Salida
NO
Análisis del problema:
Tome n = 5, k = 3 como ejemplo y divídalo en binario como (101). En este momento, hay dos 1, lo que significa que 4 + 1 se puede dividir en al menos dos, pero k = 3,
Según la naturaleza 2 n = 2 n-1 * 2
Podemos dividir el binario (101) del bit más alto al siguiente bit (021) y dividirlo en 2+ 2 +1 tres partes,
Podemos usar una cola de prioridad organizada de mayor a menor para poner 4 y 1 en la cola, sacar los bits más altos a su vez, y luego dividir los dos bits más altos por 2 y ponerlos en la cola nuevamente, sabiendo que suma = k Está satisfecho;
ACcode
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define gold_m main
using namespace std;
typedef long long ll;
const int N=1e6+10;
ll a[N];
int gold_m() {
ll n,k;
cin>>n>>k;
if(n==0&&k==0||k>n) {
cout<<"NO";
return 0;
}
ll cnt=1,sum=0;
priority_queue<ll,vector<ll>,less<ll>>heap;
while(n>0) {
if(n%2)
heap.push(n%2*cnt);
if(n%2) sum++;
cnt*=2;
n/=2;
}
if(sum>k) {
cout<<"NO";
return 0;
}
cout<<"YES"<<endl;
while(heap.size()<k) {
ll temp=heap.top();
heap.pop();
if(temp>=2) {
heap.push(temp/2);
heap.push(temp/2);
}
}
while(!heap.empty()) {
cout<<heap.top()<<" ";
heap.pop();
}
return 0;
}
Otra forma de no usar STL
La misma idea
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define gold_m main
using namespace std;
typedef long long ll;
const int N=1e6+10;
ll a[N];
int gold_m() {
ll n,k;
cin>>n>>k;
if(n==0&&k==0||k>n) {
cout<<"NO";
return 0;
}
ll cnt=0,sum=0;
while(n>0) {
a[++cnt]=n%2;
if(n%2) sum++;
n/=2;
}
ll t= cnt;
// 从高位cnt开始
while(sum<k) {
if(cnt==1)
break;
if(a[cnt]) {
a[cnt]--;
a[cnt-1]+=2;
} else {
cnt--;
}
if(a[cnt])
sum++;
}
if(sum!=k) {
cout<<"NO";
return 0;
}
cout<<"YES"<<endl;
ll temp=1;
for(int i=1 ; i<=t; i++) {
for(int j=1; j<=a[i]; j++)
cout<<temp<<" ";
temp*=2;
}
return 0;
}