构造题(agc059_b)

该文是一个编程挑战,涉及排列优化问题。给定不同颜色的球,目标是将它们放在一个圆圈上,使得颜色相邻的对数最小。通过构建图并使用深度优先搜索来解决,当特定条件满足时,直接输出所有球的颜色顺序即可达到最优解。
摘要由CSDN通过智能技术生成

https://atcoder.jp/contests/agc059/tasks/

B - Arrange Your Balls Editorial

 / 


Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 700700 points

Problem Statement

You have NN balls of colors C_1, C_2, \ldots, C_NC1​,C2​,…,CN​. Here, all colors are represented by an integer between 11 and NN inclusive. You want to arrange the balls on a circle. After you do that, you will count the number of pairs of colors (X, Y)(X,Y) such that X < YX<Y and there exist two adjacent balls of colors XX and YY.

Find an arrangement that minimizes the number of such pairs. If there are many such arrangements, find any of them.

For example, for balls of colors 1, 1, 2, 31,1,2,3, if we arrange them as 1, 1, 2, 31,1,2,3, we get 33 pairs: (1, 2), (2, 3), (1, 3)(1,2),(2,3),(1,3). If we arrange them as 1, 2, 1, 31,2,1,3, we get only 22 pairs: (1, 2), (1, 3)(1,2),(1,3).

Solve TT test cases for each input file.

Constraints

  • 1 \le T \le 5 \cdot 10^41≤T≤5⋅104
  • 3 \le N \le 2 \cdot 10^53≤N≤2⋅105
  • 1 \le C_i \le N1≤Ci​≤N
  • The sum of NN in one input file doesn't exceed 2\cdot 10^52⋅105.
  • All values in the input are integers.

Input

Input is given from Standard Input in the following format:

TT
case_1case1​
case_2case2​
\vdots⋮
case_TcaseT​

Each case is in the following format:

NN
C_1C1​ C_2C2​ \ldots… C_NCN​

Output

For each test case, output your answer in the following format:

A_1A1​ A_2A2​ \ldots… A_NAN​

Here, A_iAi​ is the color of the ii-th ball (in clockwise order) on the circle in your arrangement.

(A_1, A_2, \ldots, A_N)(A1​,A2​,…,AN​) should be a permutation of (C_1, C_2, \ldots, C_N)(C1​,C2​,…,CN​), and the number of pairs of colors (X, Y)(X,Y) such that X < YX<Y and there exist two adjacent balls of colors XX and YY, should be minimized.

If multiple solutions exist, any of them will be accepted.


Sample Input 1 Copy

Copy

3
3
1 2 3
4
1 2 1 3
5
2 2 5 3 3

Sample Output 1 Copy

Copy

1 2 3 
2 1 3 1 
3 3 2 5 2 

 

#include <bits/stdc++.h>
using namespace std;

int n, a[200005], occ[200005];
vector<int> G[200005];
set<pair<int, int> > hv;
void dfs(int v, int p)
{
    for(auto u : G[v])
    {
        if(u == p) continue;
        printf("%d ", v);
        occ[v]--;
        dfs(u, v);
    }
    while(occ[v] > 0)
    {
        printf("%d ", v);
        occ[v]--;
    }
}

void solve()
{
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
        scanf("%d", &a[i]);
    for(int i = 1; i <= n; i++)
        occ[i] = 0;
    for(int i = 0; i < n; i++)
        occ[a[i]]++;

    hv.clear();
    for(int i = 1; i <= n; i++)
        G[i].clear();
    for(int i = 1; i <= n; i++)
        if(occ[i] > 0)
            hv.insert(make_pair(occ[i], i));

    if((int)hv.size() * 2 - 2 > n)
    {
        for(int i = 1; i <= n; i++)
            for(int j = 0; j < occ[i]; j++)
                printf("%d ", i);
        printf("\n");
        return;
    }

    while(hv.size() > 1)
    {
        pair<int, int> u = *hv.begin(), v = *hv.rbegin();
        G[u.second].push_back(v.second);
        G[v.second].push_back(u.second);
        hv.erase(u);
        hv.erase(v);
        hv.insert(make_pair(v.first - 1, v.second));
    }

    dfs(hv.begin()->second, 0);
    printf("\n");
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--) solve();
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值