D. Phoenix and Socks

前言:这题真滴水。


D. Phoenix and Socks
  题目类型:贪心
  解析
  贪心思想,首先,能不花钱就不花钱,看看能不能左右匹配。
  设对于左右不同颜色的直接匹配为硬匹配,花费2元。不花钱的处理完了之后,若存在L != R的情况,此时不能直接硬匹配。如果L多,就在1~L中找找,能不能改方向,不改颜色匹配。因为此时硬匹配不但要改颜色而且要改方向,不如先在L中看看能不能同方向匹配,能的话绝对是赚的,每匹配一对,最终少改一次颜色
  最后硬匹配即可。

  code

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
 
int n,t,l,r,a[202020],col[202020],cor[202020];
 
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin >> t ;
    while(t--){
    
    
        int finish = 0 , ans = 0;
        cin >> n >> l >> r ;
        for(int i = 1 ; i <= n ; ++i){
    
    
            cin >> a[i] ;
            if(i <= l)col[a[i]]++;
            else cor[a[i]]++;
        }
        int nl = l , nr = r;
        ///处理左右匹配
        for(int i = 1 ; i <= l ; ++i){
    
    
            if(col[a[i]] && cor[a[i]]){
    
    
                col[a[i]]--;
                cor[a[i]]--;
                nl--;
                nr--;
            }
        }
        if(nl >= nr){
    
    
            ///处理左匹配
            for(int i = 1 ; i <= l ; ++i){
    
    
                if(col[a[i]] >= 2 && nl > nr){
    
    
                    col[a[i]] -= 2;
                    nl-=2;
                    ans++;
                }
            }
            ans += (nl-nr)/2 + (nl+nr)/2;
        }
        else {
    
    
            ///处理右匹配
            for(int i = l+1 ; i <= n ; ++i){
    
    
                if(cor[a[i]] >= 2 && nr > nl){
    
    
                    cor[a[i]] -= 2;
                    nr-=2;
                    ans++;
                }
            }
            ans += (nr-nl)/2 + (nr+nl)/2;
        }
        cout << ans << endl ;
        for(int i = 1 ; i <= n ; ++i)
            col[i] = cor[i] = 0;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_45699242/article/details/116382475