好耶~又是炸裂的一天
首先这次的题目难度其实中肯,T1水,T2考思维,T3大模拟,T4小清新图论,T5***。
T1 镜像字符串
然后你就可以发现它是一道水题了……
但是存在一个细节,就是当且仅当:
第一个字符与第二个字符相同,直接输出两次第一个字符。
否则遇见相同情况继续循环遍历,证明如下:
于是就可以愉快地敲代码了……
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int num=0,ch=0;
char c=getchar();
while(!isdigit(c))ch|=(c=='-'),c=getchar();
while(isdigit(c))num=(num<<1)+(num<<3)+(c^48),c=getchar();
return ch?-num:num;
}
inline void write(int x){
if(x>=10)write(x/10);
if(x<0)x=-x,putchar('-');
putchar(x%10+'0');
return;
}
int T,n,cnt;
char s[100005],s1[100005];
signed main(){
// freopen("mirror.in","r",stdin);
// freopen("mirror.out","w",stdout);
T=read();
while(T--){
cnt=0;
scanf("%d %s",&n,s);
if(s[0]==s[1]){
printf("%c%c\n",s[0],s[0]);
continue;
}
bool flag=0;
for(int i=1;i<n;++i){
if(s[i-1]<s[i]){
for(int j=0;j<i;++j)printf("%c",s[j]);
for(int j=i-1;j+1;--j)printf("%c",s[j]);
puts("");
flag=1;
break;
}
}
if(!flag){
for(int i=0;i<n;++i)printf("%c",s[i]);
for(int i=n-1;i+1;--i)printf("%c",s[i]);
puts("");
}
}
return 0;
}
T2 双端队列
题面:
题目描述
S h e r r y Sherry Sherry 现在碰到了一个棘手的问题,有 N N N 个整数需要排序。
S h e r r y Sherry Sherry 手头能用的工具就是若干个双端队列。
她需要依次处理这 N N N 个数,对于每个数, S h e r r y Sherry Sherry 能做以下两件事:
- 新建一个双端队列,并将当前数作为这个队列中的唯一的数;
- 将当前数放入已有的队列的头之前或者尾之后。
对所有的数处理完成之后, S h e r r y Sherry Sherry 将这些队列排序后就可以得到一个非降的序列。
输入格式
第一行包含一个整数 N N N,表示整数的个数。接下来的 N N N 行每行包含一个整数 D i D_i Di,其中 D i D_i Di 表示所需处理的整数。
输出格式
其中只包含一行,为 S h e r r y Sherry Sherry 最少需要的双端队列数。
样例
样例输入
6
3
6
0
9
6
3
样例输出
2
首先这是一道思维题,我们首先将元素标个号之后进行排序,然后容易发现以下性质:
任意队列
i
d
id
id(即预处理标号的变化趋势,按照排序后遍历),总会有
i
d
id
id 先降后升。
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int num=0,ch=0;
char c=getchar();
while(!isdigit(c))ch|=(c=='-'),c=getchar();
while(isdigit(c))num=(num<<1)+(num<<3)+(c^48),c=getchar();
return ch?-num:num;
}
inline void write(int x){
if(x>=10)write(x/10);
if(x<0)x=-x,putchar('-');
putchar(x%10+'0');
return;
}
int n,loc,_loc=1,tmp,Min=1145141919810,Max=-1145141919810,ans=1;
struct Q{
int num,id;
}a[200005];
inline bool cmp(Q x,Q y){return x.num==y.num?x.id<y.id:x.num<y.num;}
signed main(){
// freopen("queue.in","r",stdin);
// freopen("queue.out","w",stdout);
n=read();
for(int i=1;i<=n;++i)a[i].num=read(),a[i].id=i;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;++i){
if(a[i].num!=a[i+1].num){
loc=i;
if(!tmp){
if(a[loc].id<=Min){
Min=a[_loc].id;
}else{
tmp^=1;
Max=a[loc].id;
}
}else{
if(a[_loc].id>=Max){
Max=a[loc].id;
}else{
++ans;
tmp^=1;
Min=a[_loc].id;
}
}
_loc=i+1;
}
}
write(ans);
return 0;
}
T3 时间复杂度
纯模拟,没有什么好说的,注意细节(所以你就可以看见我花花绿绿的分数)。
……
T4 软件安装
强连通分量+缩点+树形DP
强连通分量跑几遍 Tarjan
就不必多说了,缩点也可以用 并查集
,主要是为了处理环的情况,最后跑一遍 DP
.
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int num=0,ch=0;
char c=getchar();
while(!isdigit(c))ch|=(c=='-'),c=getchar();
while(isdigit(c))num=(num<<1)+(num<<3)+(c^48),c=getchar();
return ch?-num:num;
}
inline void write(int x){
if(x>=10)write(x/10);
if(x<0)x=-x,putchar('-');
putchar(x%10+'0');
return;
}
int n,m,w[105],v[105],Dfn[105],per[105],low[105],cnt,ret,dp[105][505],CR[105],siz[105],MJL[105];
struct Q{
int W,V;
}a[105];
vector<int>G[105],G1[105];
stack<int>s;
inline void dfs(int x){
Dfn[x]=low[x]=++cnt,s.push(x);
for(int i=0;i<G[x].size();++i){
if(!Dfn[G[x][i]]){
dfs(G[x][i]);
low[x]=min(low[x],low[G[x][i]]);
}else if(!per[G[x][i]]){
low[x]=min(low[x],Dfn[G[x][i]]);
}
}
if(low[x]==Dfn[x]){
++ret;
while(1){
int tmp=s.top();s.pop();
per[tmp]=ret;
a[ret].V+=v[tmp];
a[ret].W+=w[tmp];
if(tmp==x)break;
}
}
return;
}
inline void Dfs(int x){
MJL[++MJL[0]]=x;
for(int i=0;i<G1[x].size();++i){
Dfs(G1[x][i]);
siz[x]+=siz[G1[x][i]];
}
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;++i)w[i]=read();
for(int i=1;i<=n;++i)v[i]=read();
for(int i=1;i<=n;++i){
int x=read();
G[x].push_back(i);
}
for(int i=1;i<=n;++i){
if(!Dfn[i]){
dfs(i);
}
}
for(int i=1;i<=n;++i){
for(int j=0;j<G[i].size();++j){
if(per[i]!=per[G[i][j]]){
G1[per[i]].push_back(per[G[i][j]]);
++CR[per[G[i][j]]];
}
}
}
for(int i=1;i<=ret;++i){
if(!CR[i]){
G1[0].push_back(i);
}
siz[i]=1;
}
siz[0]=1;
Dfs(0);
for(int i=ret+1;i;--i){
for(int j=1;j<=m;++j){
dp[i][j]=dp[i+siz[MJL[i]]][j];
if(j>=a[MJL[i]].W)dp[i][j]=max(dp[i][j],dp[i+1][j-a[MJL[i]].W]+a[MJL[i]].V);
}
}
write(dp[1][m]);
return 0;
}