CF1300 C.アヌは、機能を持っています
質問の意味:
操作があります\(F(X、Y)=(X- | y軸)-y \) 、あなたの順序を与えるには、\(A_1、A_2、...、A_N \) 。
あなたは配列を変更することができ\(A \)を順次、その結果、\(F(F(... F (F(A_1、A_2)、A_3)、...、A_ {N-1})、A_N)\ )最大。
アイデア:
私たちは、彼が何を表しているような操作を参照してください?
我々\(X、Yは、\)バイナリに分解し、\(X- | Y- \)が 1-1を持っている2人のパーティーをしましょうと等価であり、その後、\( - Y \)させることです\(Y \)そこから1つのを引いた位置。
例えば、言う(= X-1101、Y-0111 = \)\、それは、と言うのと等価である\(X \)第離れる最後の1と1インチ
場所に、何回も(1より大きい)があった場合は、すべての数字ダウンバイナリ1に、そして1は確かにこの位置を維持することはできません。
我々は1の最高の発生を見つけて、それからだけでデジタル表示された後、前にそれを置きます。
このサンプルは、どのようなシミュレートすることができます\(9 \ 5 \ 9 \) 、\(5 \) 、最適なソリューションの上に置かれています。
私はまだ説明するのか分かりません...
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int n, a[maxn];
int num[40];
int cnt;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
int x = a[i];
int tmp = 0;
while(x)
{
if(x&1) num[tmp++] += 1;
else num[tmp++] += 0;
x >>= 1;
}
cnt = max(cnt, tmp);
}
int pos = -1;
for(int i = cnt-1; i >= 0; i--)
if(num[i] == 1)
{
pos = i;
break;
}
if(pos == -1)
{
for(int i = 1; i <= n; i++)
printf("%d ", a[i]);
return 0;
}
for(int i = 1; i <= n; i++)
{
if(a[i]>>pos&1)
{
swap(a[i], a[1]);
break;
}
}
for(int i = 1; i <= n; i++)
printf("%d ", a[i]);
return 0;
}