前言:

这把也是相当极限,只A了3题,而且吃了不少罚时,幸好最后排名卡住,还上了一分,算是测试了一下排名极限了(笑哭)


**#A.Simple Palindrome# **

难度正常,但是第一次wa了,虽然后面做出来了,但还是一直没想明白,为什么aeioua的回文子串数量会高与aaeiou 后来去看解析,原来是aea这样也会算(被自己蠢哭)。

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
void solve() {
   int n;
   cin>>n;
   char a[6] = {'a','e','i','o','u'};
   int cnt = 0;
   int num = n/5;
   int b[6] = {0,0,0,0,0,0};
   for(int i=1;i<=n;i++){
        b[cnt++]++;
        if(cnt==5) cnt =0;
   }
   for(int i=1;i<=5;i++){
      for(int j=1;j<=b[i-1];j++){
        cout<<a[i-1];
      }
   }
   cout<<endl;
}
int main() {
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

B.The Strict Teacher

问题差别就是差在老师数量和查询数量上

思路:由于n的范围很大在3-1e9之间,直接算不太现实,考虑分隔,最开始和结束肯定是只靠近一个点,很好算,就是中间的点,必然有两个点包围着,如何确定一个大于(题意不会等)某个数的位置,这里考虑二分,(在这里想了很久,不知道会不会超时,一直没敢写,浪费了不少时间。。。)

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
void solve() {
   int n,m,q;
   cin>>n>>m>>q;
   vector<int> b;
   map<int,int> qq;
   for(int i=1;i<=m;i++){
        int t;
        cin>>t;
        b.push_back(t);
        qq[t] = 1;
   }
   sort(b.begin(),b.end());
   int mx,mi;
    mx = b[b.size()-1],mi=b[0];
   while(q--){
    int t;
    cin>>t;
        if(t<mi){
            cout<<mi-1<<endl;
        }
        else if(t>mx){
            cout<<n-mx<<endl;
        }
        else{
        //直接手搓二分
            int l = -1 , r = m;
            while(l+1<r){
                int mid = (l+r)/2;
                if(b[mid]>t) r = mid;
                else l = mid;
            }
            cout<<(b[r]-b[r-1]-1)/2+((b[r]-b[r-1]-1)%2!=0)<<endl;
        }
    }
}
int main() {
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

C题也是有点超出能力范围了,主要是dp不太会,还是得加练。。。

设状态转移方程为dp[i][k]; 表示前i行所能到达的字母所能得到的最大分值,

然后就是不断转移

从k转移到一个值,要求遍历i这个字符串,顺便把增加的值累积一下,就可以完成转移

写法很奇特,又学到一种写法(膜拜大佬)

#include <bits/stdc++.h>
using namespace std;
int n,m;
int dp[1005][5];
string t = "narek";
pair<int,int> sum(string s,int x){
    int ans = 0;
    for(int i=0;i<m;i++){
        if(s[i]==t[x]){
            x++;
            if(x==5) ans+=10,x=0;
            //这里加10,不仅是因为+5而且ai也失去了这5分,一增一减累计10分
        }
        if(t.find(s[i])!= string::npos) ans--;
    }
    return {ans,x};

}
void solve(){
    cin>>n>>m;
    for(int i=0;i<=n;i++){
        for(int j=0;j<=4;j++){
            dp[i][j] = -2e9;
        }
    }
    dp[0][0] = 0;
    for(int i=1;i<=n;i++){
        string s;
        cin>>s;
        for(int j=0;j<=4;j++){
            dp[i][j] = max(dp[i][j],dp[i-1][j]);
            pair<int,int> temp = sum(s,j);
            int cj = temp.first , vj = temp.second;
            dp[i][vj] = max(dp[i][vj],dp[i-1][j] + cj); 
        }
    }
    int mx = 0;
    for(int i=0;i<=4;i++){
        mx = max(mx,dp[n][i]);
    }
    cout<<mx<<endl;
}
int main()
{
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}
//怎么找到最优的拼接字符串,计算最值
//选或不选,考虑动态规划 dp[i][mxt(a[i],j)] = dp[i-1][j] + sorce; 
//状态
//转移方程
//答案