1. 程式人生 > >codeforces 794C Naming Company(貪心)

codeforces 794C Naming Company(貪心)

題意:

x,y兩人輪流從各自的字串a,b(長度都為n)裡選擇字元,形象的來說就是往一個長度為n裡的容器裡放所選擇的字元,x先手,x想最後的字典序越小越好,y想最後的字典序越大越好,問他們兩都採取最優的策略,問最後獲得的字串是什麼

解題思路:

首先我們容易想到,x只能取出前n/2小的字元來投放,並且,最後字元的位置一定是字典序遞增的,因為想最後的字典序最小,而y是隻能取出前n/2大的字元,並且是最後字元的位置一定是字典序遞劍的。

然後就是投放位置的問題。

當輪到x放的時候,假如當前字典序最小的字元都大於等於(等於非常重要)b的字典序最大的字串了,那麼就應該讓b的字元越往前放越好,所以應該要讓自己字典序最大(因為對於x來說,一定按字典序遞增)的字元先放在最後一個位置上。

y的話正好相反

為什麼等於也要這樣放呢?賽時沒過就是因為我沒有加等於QAQ

因為a字串當前字元之後的字元可能大於b裡所有的字元,

比如

a:abc

b:aaa

如果不加等於號得到的就是aba    順序為a--,a-a,aba

加了等於號就是aab 順序為--b,-ab,aab

對於x來說明顯第二種最優。

所以等於號一定要加。

程式碼:

#include <bits/stdc++.h>

using namespace std;
const int maxn=3e5+5;
char a[maxn];
char b[maxn];
char c[maxn];
bool cmp(char x, char y)
{
    return x>y;
}
int main()
{
    scanf("%s%s", a, b);
    int i, j, n=strlen(a);
    sort(a, a+n);
    sort(b, b+n, cmp);
//    printf("%s\n", b);
    i=j=0;

    int k=0, l=0, r=n-1, ir=(n-1)/2, jr=(n-1)/2;
    if(n%2)jr--;
    while(k<n)
    {
        if(k%2==0)
        {
        if(a[i]>=b[j])
        {
            c[r--]=a[ir--];
        }
        else
        {
            c[l++]=a[i++];
        }

        }
        else
        {
            if(b[j]<=a[i])
            {
                c[r--]=b[jr--];
            }
            else c[l++]=b[j++];

        }
        k++;
    }
    printf("%s\n", c);
//    j=0, k=0;
//    for(i=0; i<n; i++)
//    {
//        if(i%2==0)printf("%c", a[j++]);
//        else printf("%c", b[k++]);
//    }
    return 0;
}