前言:
这把也是相当极限,只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;
//状态
//转移方程
//答案