A题
题意:按照身高给n个成员排序,要求尽可能让相邻两人的身高平均数是整数,给出方案
解:直接分奇偶数输出即可
#include<bits/stdc++.h>
using namespace std;
 
const int maxn = 1e4 + 10;
int t,n,a[maxn];
 
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i = 1;i <= n; ++i) cin>>a[i];
        int f = 0;
        for(int i = 1;i <= n; ++i)
            if(a[i] % 2)
            {
                if(f) cout<<' ';
                f = 1;
                cout<<a[i];
            }
        for(int i = 1;i <= n; ++i)
            if(a[i] % 2 == 0)
            {
                if(f) cout<<' ';
                f = 1;
                cout<<a[i];
            }
        cout<<endl;
    }
    return 0;
}
B题
题意:一个仅由‘T’和‘M’组成的字符串,能否分成若干个“TMT”的子序列
解:首先M的数量*2是T的数量,然后看M的前后是否都有足够的T即可
#include<bits/stdc++.h>
using namespace std;
 
const int maxn = 1e4 + 10;
int t,n,a[maxn];
string s;
 
bool solve()
{
    int st = 0,sm = 0,q = 0;
    for(int i = 0;i < n; ++i)
    {
        if(s[i] == 'T') st++,q++;
        else
        {
            sm++;
            if(!q) return 0;
            q--;
        }
    }
    return 1;
}
 
bool check()
{
    if(!solve()) return 0;
    reverse(s.begin(),s.end());
    return solve();
}
 
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        cin>>s;
        int num = 0;
        for(int i = 0;i < n; ++i)
            if(s[i] == 'M') num++;
        if(num * 3 != n)
        {
            cout<<"NO\n";
            continue;
        }
        if(!check()) cout<<"NO\n";
            else cout<<"YES\n";
    }
    return 0;
}
C题
题意:定义di = max(a1,a2,...ai) - min(a1,a2,...ai),对a数组排序使得d1+d2+...+dn最小,输出d1+d2+...+dn
解:
Th1   将a进行排序,dn确定,然后枚举每一步删掉了哪个数字,记忆化一下
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
ll n,a[2010];
ll f[2010][2010];

ll solve(int l,int r)
{
    if(l == r) return 0;
    if(f[l][r]) return f[l][r];
    return f[l][r] = min(solve(l,r - 1),solve(l + 1,r)) + a[r] - a[l];
}

int main()
{
    cin>>n;
    for(int i = 1;i <= n; ++i)
        cin>>a[i];
    sort(a + 1,a + n + 1);
    cout<<solve(1,n)<<endl;
    return 0;
}
结果光荣的TLE在了test18

Th2 你都记忆化了为啥不直接DP呢,也对哈,注意下枚举的顺序就行啦,区间DP走起
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
ll n,a[2010],f[2010][2010];

ll solve()
{
    for(int i = 1;i <= n; ++i)
        for(int j = 1;j <= n; ++j)
            f[i][j] = 1e18;
    for(int i = 1;i <= n; ++i) f[i][i] = 0;
    for(int i = n - 1;i >= 1; --i)
        for(int len = 1;len + i <= n; ++len)
        {
            f[i][i + len] = min(f[i][i + len],f[i + 1][i + len] + a[i + len] - a[i]);
            f[i][i + len] = min(f[i][i + len],f[i][i + len - 1] + a[i + len] - a[i]);
            ///printf("f[%d][%d] = %d\n",i,i + len,f[i][i + len]);
        }
    return f[1][n];
}

int main()
{
    cin>>n;
    for(int i = 1;i <= n; ++i) cin>>a[i];
    sort(a + 1,a + n + 1);
    cout<<solve()<<endl;
    return 0;
}
D题
题意:给你3个长度为2*n的01串,要求构造一个长度不大于3*n的01串,使得给出的3个串至少两个能作为答案的子序列
解:瞎搞瞎搞
#include<bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 10;
int t,n,t1,t2,t3;
string s1,s2,s3,a,b,ans,s;

int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        cin>>s1>>s2>>s3;
        ans = "";
        t1 = t2 = t3 = 0;
        while(t1 < 2 * n && t2 < 2 * n && t3 < 2 * n)
        {
            int k = (s1[t1] == '0') + (s2[t2] == '0') + (s3[t3] == '0');
            char ch = (k >= 2)?'0':'1';
            ans += ch;
            if(s1[t1] == ch) t1++;
            if(s2[t2] == ch) t2++;
            if(s3[t3] == ch) t3++;
        }
        if(t1 == 2 * n)
            if(t2 >= t3) while(t2 < 2 * n) ans += s2[t2++];
                else while(t3 < 2 * n) ans += s3[t3++];
        if(t2 == 2 * n)
            if(t1 >= t3) while(t1 < 2 * n) ans += s1[t1++];
                else while(t3 < 2 * n) ans += s3[t3++];
        if(t3 == 2 * n)
            if(t2 >= t1) while(t2 < 2 * n) ans += s2[t2++];
                else while(t1 < 2 * n) ans += s1[t1++];
        cout<<ans<<endl;
    }
    return 0;
}
E题
题意:求n的第k个满足a(i+1)>=a(i)-1的排列