Codeforces Round 910 (Div. 2)
比赛录屏
https://www.bilibili.com/video/BV1kN411T71H/?spm_id_from=top_right_bar_window_dynamic.content.click
\(A. Milica and String\)
https://codeforces.com/contest/1898/submission/233431132
\(B. Milena and Admirer\)
https://codeforces.com/contest/1898/submission/233437664
\(C. Colorful Grid\)
https://codeforces.com/contest/1898/submission/233454141
\(D. Absolute Beauty\)
https://codeforces.com/contest/1898/submission/233463980
\(E. Sofia and Strings\)
题意:给定一个字符串 \(s\) ,可以对它进行以下两种操作:选择一个字符 \(s_i\) ,并删除该字符;选择一个区间 \([l,r]\) ,进行升序排序。询问进行上述任意次操作后,能否得到字符串 \(t\) 。
解法:应该比较显然的,我们可以选择相邻两个字符进行操作二,这样相当于对字典序降序的相邻字符可以做移动操作。那么对于 \(t_i\) 来说,我们肯定希望当前 \(s\) 中第一个未使用的相同字母作为 \(t_i\) 。这样选择之后,那么对于 \(s\) 中这个字母之前的所有未使用且字典序小于自己的都是必须删除的。
赛场上思路比较模糊,想尽快写出来就开始瞎写了。
void solve(){
int n=read(),m=read();
string s,t,res;
cin>>s>>t;
queue<int>dic[30];
for(int i=0;i<n;i++){
dic[s[i]-'a'].push(i);
}
for(int i=0;i<m;i++){
if(dic[t[i]-'a'].size()){
int idx=dic[t[i]-'a'].front();
for(int j=0;j<=t[i]-'a';j++){
while(dic[j].size()&&dic[j].front()<=idx){
dic[j].pop();
}
}
}else{
cout<<"NO\n";
return ;
}
}
cout<<"YES\n";
// puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}
\(F. Vova Escapes the Matrix\)
题意:给定一个迷宫和一个起点,迷宫分为空格子和有遮挡物的格子。若从起点顺着空格子走到边缘则能够走出,接下来迷宫分为三种类型:无法被走出;只有一个出口能走出;有两个及以上出口能走出。接下来可以选择堵住迷宫的一些格子,但是要求堵住以后的迷宫不改变其类型,求最多能堵住多少格子。
解法:对于类型1,将迷宫中所有空格子全部堵住即可。对于类型2而言,将迷宫起点到出口最短路留下,其余全部堵住即可。
而对于类型3,需要保留两个出口,其余的全部都填满。即两个出口到起点的最短路保留,其余全部填满,但是需要注意的是可能两个出口到起点的最短路有重复点,需要特别处理。对于起点到任意一点的最短路我们可以直接一遍BFS求得,但是如何求起点到两个出口的最短路,我们可以通过逆向思维,从每个终点出发开始BFS,然后任意一个空格子可以被走过最多两次,这样能保证有两个终点走到该点上。因为是BFS,所以最先走到某个格子的两个终点必然是最短的,然后再记录一下终点到该格子的距离。最终求答案的过程我们可以遍历每一个空格子,然后假设起点到这个格子是两个最短路的重合段,用起点到该格子的距离加上两个终点到该格子的距离就是两个最短路的非重复的格子数。最后用总空格子数减去最小的非重复格子数就是答案。
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
void solve(){
int n=read(),m=read();
vector<string>s(n);
int vx=0,vy=0,emp=0;
for(int i=0;i<n;i++){
cin>>s[i];
for(int j=0;j<m;j++){
if(s[i][j]=='V'){
vx=i,vy=j;
}
if(s[i][j]=='.'){
emp++;
}
}
}
int ans=emp,dis[n][m],cnt=0;
memset(dis,-1,sizeof(dis));
queue<PII>q;
q.push((PII){vx,vy});
dis[vx][vy]=0;
while(q.size()){
auto [x,y]=q.front();
q.pop();
if(x==0||y==0||x==n-1||y==m-1){
cnt++;
}
for(int k=0;k<4;k++){
int nx=x+dx[k],ny=y+dy[k];
if(0<=nx&&nx<n&0<=ny&&ny<m&&dis[nx][ny]==-1&&s[nx][ny]!='#'){
dis[nx][ny]=dis[x][y]+1;
q.push((PII){nx,ny});
}
}
}
if(cnt==0){
ans=0;
}else if(cnt==1){
for(int x=0;x<n;x++){
for(int y=0;y<m;y++){
if((x==0||y==0||x==n-1||y==m-1)&&(dis[x][y]!=-1)){
ans=min(ans,dis[x][y]);
}
}
}
}else{
queue<array<int,4> >q;
array<int,2>dise[n][m],ex[n][m];
// memset(dise,-1,sizeof(dise));
// memset(ex,-1,sizeof(ex));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
dise[i][j][1]=ex[i][j][1]=dise[i][j][0]=ex[i][j][0]=-1;
}
}
for(int x=0;x<n;x++){
for(int y=0;y<m;y++){
if((x==0||y==0||x==n-1||y==m-1)&&s[x][y]!='#'){
q.push((array<int,4>){x,y,0,x*m+y});
}
}
}
while(q.size()){
auto [x,y,d,e]=q.front();
q.pop();
if(dise[x][y][0]==-1){
dise[x][y][0]=d;
ex[x][y][0]=e;
}else if(dise[x][y][1]==-1&&e!=ex[x][y][0]){
dise[x][y][1]=d;
ex[x][y][1]=e;
}else continue;
for(int k=0;k<4;k++){
int nx=x+dx[k],ny=y+dy[k];
if(0<=nx&&nx<n&&0<=ny&&ny<m&&s[nx][ny]!='#'){
q.push((array<int,4>){nx,ny,d+1,e});
}
}
}
for(int x=0;x<n;x++){
for(int y=0;y<m;y++){
if(dis[x][y]!=-1&&dise[x][y][1]!=-1){
ans=min(ans,dis[x][y]+dise[x][y][0]+dise[x][y][1]);
}
}
}
}
ans=emp-ans;
cout<<ans<<'\n';
//puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}

浙公网安备 33010602011771号