CF1300 C.アヌは、機能を持っています

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;
}

おすすめ

転載: www.cnblogs.com/zxytxdy/p/12289701.html