本来以为 B2 难度会 1900 什么的,结果感觉 1200 还没有,先做的 B1,后悔了 QwQ
关于我现场没切出 C 这件事…… 现场排名:
构造一个长度为 n n n 的字符串,只包含 a
e
i
o
u
五种字母,需要使得构造出来的字符串所包含的 回文 子序列 数量最小
当 n ≤ 5 n\le 5 n≤5 时,只要 5 5 5 个字母不重复出现都是最优情况
当 n > 5 n > 5 n>5 时,可以证明:
#include
using namespace std;
string str(int num,string t){
string ret;
while(num!=0){
num--;
ret+=t;
}
return ret;
}
void solve(){
int n;
cin>>n;
int k=n/5; //向下取整
string ans="";
ans+=str(k,"a");
if(n%5!=0) ans+='a',n--;
ans+=str(k,"e");
if(n%5!=0) ans+='e',n--;
ans+=str(k,"i");
if(n%5!=0) ans+='i',n--;
ans+=str(k,"o");
if(n%5!=0) ans+='o',n--;
ans+=str(k,"u");
if(n%5!=0) ans+='u',n--;
cout<<ans<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
2 2 2 个老师分别在 b 1 , b 2 b_1,b_2 b1,b2,学生在 a 1 a_1 a1,每次老师和学生必须在 [ 1 , n ] [1,n] [1,n] 之间且必须为整数,要么不动要么移动一格,若双方都用最优策略,老师至少要多少秒才能抓到学生?
保证 b 1 ≠ b 2 b_1 \ne b_2 b1=b2 且 a 1 ≠ b 1 a_1 \ne b_1 a1=b1, a 1 ≠ b 2 a_1 \ne b_2 a1=b2
将 b b b 排序 ( 1 ≤ b 1 < b 2 ≤ n ) (1 \le b_1 < b_2\le n) (1≤b1<b2≤n),分类讨论:
a 1 < b 1 a_1 < b_1 a1<b1,答案为 ( b 1 − k ) + ( k − 1 ) = b 1 − 1 (b_1-k)+(k-1) =b_1-1 (b1−k)+(k−1)=b1−1
b 1 < a 1 < b 2 b_1
a 1 > b 2 a_1>b_2 a1>b2,答案为 ( k − b 2 ) + ( n − k ) = n − b 2 (k-b_2)+(n-k)=n-b_2 (k−b2)+(n−k)=n−b2
#include
#define int long long
using namespace std;
void solve(){
int n,m,q;
int b1,b2;
int k;
cin>>n>>m>>q>>b1>>b2>>k;
if(b1>b2){
swap(b1,b2);
}
if(k>b1&&k<b2){
cout<<(b2-b1)/2<<endl;
}else if(k<b1){
cout<<b1-1<<endl;
}else{
cout<<n-b2<<endl;
}
}
signed main(){
int t=1;
cin>>t;
while(t--){
solve();
}
return 0;
}
有 m m m 个老师,第 i i i 个在 b i b_i bi, q q q 个学生,第 j j j 个在 a j a_j aj,每次老师和学生必须在 [ 1 , n ] [1,n] [1,n] 之间且必须为整数,要么不动要么移动一格,若双方都用最优策略,那么对于每一名学生,老师抓到他至少要多少秒?
保证 b i b_i bi 互不相同,且 a j ≠ b i ( 1 ≤ i ≤ m , 1 ≤ j ≤ q ) a_j \ne b_i (1\le i \le m,\ 1 \le j \le q) aj=bi(1≤i≤m, 1≤j≤q)
类似地,像 B1 一样,如何找到像 b 1 , b 2 b_1,b_2 b1,b2 一样的区间呢?
考虑 二分 出第一个大于 a j a_j aj 的 b i b_i bi,并按照上述方法判断即可
#include
#define int long long
using namespace std;
void solve(){
int n,m,q;
cin>>n>>m>>q;
vector<int> b(m);
for(int i=0;i<m;i++){
cin>>b[i];
}
sort(b.begin(),b.end());
while(q--){
int k;
cin>>k;
int pos=upper_bound(b.begin(),b.end(),k)-b.begin();
if(pos==0){
cout<<b[0]-1<<endl;
}else if(pos==m){
cout<<n-b[m-1]<<endl;
}else{
cout<<(b[pos]-b[pos-1])/2<<endl;
}
}
}
signed main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
在所给的 n n n 个长度为 m m m 的字符串选择任意多个(可能是 0 0 0 个),不改变顺序拼接在一起,选择子序列narek
,每选一个 Narek 的得分 + 5 +5 +5,否则若当前字符没有被 Narek 选中,则 GPT 得 1 1 1 分
使 S c o r e N a r e k − S c o r e G p t Score_{Narek}-Score_{Gpt} ScoreNarek−ScoreGpt 最大化,求这个值
考虑动态规划,将二维数组优化成一维,按要求模拟计分即可,每次:
t m p [ n e x t ] = max ( t m p [ n e x t ] , d p [ j ] + r e s ) ; tmp[next]=\max(tmp[next],dp[j]+res); tmp[next]=max(tmp[next],dp[j]+res);
#include
using namespace std;
const int inf=2e9;
string t="narek";
void solve(){
int n,m;
cin>>n>>m;
vector<string> s(n);
for(int i=0;i<n;i++){
cin>>s[i];
}
vector<int> dp(5,-inf),tmp;
dp[0]=0;
for(int i=0;i<n;i++){
tmp=dp;
for(int j=0;j<5;j++){
if(dp[j]==-inf){
continue;
}
int res=0,nxt=j;
for(int k=0;k<m;k++){
int p=-1;
for(int a=0;a<5;a++){
if(t[a]==s[i][k]){
p=a;
break;
}
}
if(p==-1) continue;
if(p==nxt){
nxt=(nxt+1)%5;
res++;
}else{
res--;
}
}
tmp[nxt]=max(tmp[nxt],dp[j]+res);
}
dp=tmp;
}
int ans=0;
for(int i=0;i<5;i++){
ans=max(ans,dp[i]-2*i);
}
cout<<ans<<endl;
}
int32_t main(){
int tt;
cin>>tt;
while(tt--){
solve();
}
return 0;
}