A,B就不说了 水题

 

C题的话数据很大 我一开始想到离散化 然后用了个最长连续子序列 但是忘记考虑题目有限制长度为k

所以前面wa了几个点

想了想 用map做比较好 又简单,题目就变得很水

#include <iostream>
#include <map>
using namespace std;
int n, k;
int c[300005];
map<int, int> mp;
int main(void)
{
  cin >> n >> k;
  for(int i = 1; i <= n; i++) cin >> c[i];
  for(int i = 1; i <= k; i++) mp[c[i]]++;
  int ans = mp.size();
  for(int i = k+1; i <= n; i++){
    mp[c[i]]++;
    mp[c[i-k]]--;
    if(mp[c[i-k]] == 0) mp.erase(c[i-k]);
    ans = max(ans, (int)mp.size());
  }
  cout << ans << endl;
  return 0;
}

 

D题 一个简单的dp应用

相对位置来看无非东南和东北两种走向,所以直接做两次dp,答案统计最小值即可

#include <bits/stdc++.h>
 
using namespace std;
const int maxn = 1100;
const long long INF = 0x3f3f3f3f;
typedef long long ll;
ll n,m,k,a[maxn][maxn],dp[maxn][maxn];
int main(){
    cin >> n >> m >> k;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            cin >> a[i][j];
        }
    }
    for(int i=0;i<=n;++i) dp[i][0]=1e18;
    for(int j=0;j<=m;++j) dp[0][j]=dp[n+1][j]=1e18;
    ll ans=1e18;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            dp[i][j]=min(a[i][j],min(dp[i-1][j],dp[i][j-1])+k);
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            ans=min(ans,a[i][j]+k+min(dp[i-1][j],dp[i][j-1]));
        }
    }
    for(int i=n;i;--i){
        for(int j=1;j<=m;++j){
            dp[i][j]=min(a[i][j],min(dp[i+1][j],dp[i][j-1])+k);
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            ans=min(ans,a[i][j]+k+min(dp[i+1][j],dp[i][j-1]));
        }
    }
    printf("%lld\n",ans);
    return 0;
}

 

 

E题写对了 后来晚上有事情F题没写(bushi)

等我下完课回来更。