D - Shuffle'm Up https://vjudge.net/contest/547627#problem/D
思路:单纯的模拟这个过程,在一定次数后,字符串s就会变回到最初的样子,此时就可以断定无论操作多少次,也不能成功。这需要将一开始的样子保存起来。
由于是多组输入,注意数组的初始化。
代码实现
#include <iostream>
#include<string.h>
char s1[105],s2[105];
int len;
void build_str(char *original,char *str)//保存将字符串拼接,同时将一开始的样子保存,以便于后续判断是否回到起点
{
strcpy(original,s1);
for(int i=len;i<2*len;i++)
{
original[i]=s2[i-len];
}
strcpy(str,original);
}
void solve(char *s)//开始模拟
{
int ans=0;
char str[205]={0};
char Original[205]={0};
build_str(Original,str);
do{
if(strcmp(str,s)==0)
{
printf("%d\n",ans);
return;
}
for(int i=0;i<len;i++)//交叉
{
str[i*2]=s2[i];
str[i*2+1]=s1[i];
}
for(int i=0;i<len;i++)//将前半断赋给s1,后半给s2
{
s1[i]=str[i];
s2[i]=str[i+len];
}
ans++;
}while(strcmp(str,Original)!=0);//回到起点,退出循环
printf("-1\n");
}
int main()
{
int t;
scanf("%d",&t);
getchar();
int num=1;
while(t--)
{
scanf("%d",&len);
getchar();
scanf("%s",s1);
getchar();
scanf("%s",s2);
getchar();
char s[205]={0};
scanf("%s",s);
getchar();
printf("%d ",num++);
solve(s);
}
return 0;
}
F - Oil Deposits https://vjudge.net/contest/547627#problem/F
思路:联通块问题,从第一个位置开始遍历,发现一个要塞就把它自己和与其相连的所有@给消除,防止二次发现,同时计数。相处操作为dfs,从发现的要塞往八个方向,去搜索,搜索到白色要塞就消除。一直遍历到最后。这样就实现了,发现联通块和消除联通块的目的。
代码实现
#include <iostream>
#include<string.h>
int m,n;
char mapp[105][105];
int dx[8]={0,1,0,-1,1,-1,1,-1};
int dy[8]={1,0,-1,0,1,-1,-1,1};
void dfs(int x,int y)//十分普通的dfs,不用回溯
{
int tx,ty;
for(int i=0;i<8;i++)
{
tx=x+dx[i];
ty=y+dy[i];
if(tx>=0&&ty>=0&&tx<m&&ty<n)
{
if(mapp[tx][ty]=='@')
{
mapp[tx][ty]='*';
dfs(tx,ty);
}
}
}
}
int main()
{
while(1)
{
scanf("%d%d",&m,&n);
getchar();
if(m==0) break;
int ans=0;
for(int i=0;i<m;i++)
{
scanf("%s",mapp[i]);
getchar();
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(mapp[i][j]=='@')//发现要塞
{
ans++;
mapp[i][j]='*';//消除与其相连的要塞
dfs(i,j);
}
}
}
printf("%d\n",ans);
}
return 0;
}
G - Find a way https://vjudge.net/contest/547627#problem/G
思路:在y和m处,分别使用一次bfs。记录他们达到每个kfc的时间,同一个kfc就把时间相加。
找到里面的最小值。
注意初始化book数组
代码实现:
#include <iostream>
#include<string.h>
int n,m;
char mapp[205][205];
int yx,yy,mx,my;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int kfc[205][205];
struct point{
int x;
int y;
int ti;
}que1[40005],que2[40005];
void find_ym()//找到y和m,同时初始化kfc
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mapp[i][j]=='Y')
{
yx=i;
yy=j;
}
if(mapp[i][j]=='M')
{
mx=i;
my=j;
}
kfc[i][j]=0;
}
}
}
void bfs(point *que,int book[205][205],int sx,int sy)
{
int tail=0;
int head=0;
que[head].x=sx;
que[head].y=sy;
que[head].ti=0;
book[sx][sy]=1;
int nx,ny,nt;
int tx,ty;
while(head<=tail)
{
nx=que[head].x;
ny=que[head].y;
nt=que[head].ti;
if(mapp[nx][ny]=='@')
{
kfc[nx][ny]+=nt;
}
for(int i=0;i<4;i++)
{
tx=nx+dx[i];
ty=ny+dy[i];
if(tx>=0&&ty>=0&&tx<n&&ty<m)
{
if(book[tx][ty]==0&&mapp[tx][ty]!='#')
{
que[++tail].x=tx;
que[tail].y=ty;
que[tail].ti=nt+1;
book[tx][ty]=1;
}
}
}
head++;
}
}
void output()
{
int min=440000;
for(int i=0;i<n;i++)//找到最短总时间
{
for(int j=0;j<m;j++)
{
if(kfc[i][j]!=0&&kfc[i][j]<min)//此kfc可以抵达
{
min=kfc[i][j];
}
}
}
printf("%d\n",min*11);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
getchar();
int book1[205][205]={0};
int book2[205][205]={0};
for(int i=0;i<n;i++)
{
scanf("%s",mapp[i]);
getchar();
}
find_ym();
bfs(que1,book1,yx,yy);//从y开始bfs
bfs(que2,book2,mx,my);//从m开始bfs
output();
}
return 0;
}