https://vjudge.net/contest/547627#problem/F
求解联通块个数的问题,解法思路:遍历地图,遍历到@符号,将相连的@全部标记,下次不再遍历,计数即可。
#include<iostream>
using namespace std;
char a[101][101];
int book[101][101];
int net[8][2]={{1,0},{-1,0},{0,1},{0,-1},{-1,1},{1,-1},{1,1},{-1,-1}};
int ans,n,m;
void dfs(int x,int y)
{
book[x][y]=1;//标记为搜索过
for(int i=0;i<8;i++)//搜索8个位置
{
int tx=x+net[i][0];
int ty=y+net[i][1];
if(tx<1||ty<1||tx>n||ty>m||book[tx][ty]!=0)continue;
if(a[tx][ty]=='@'&&book[tx][ty]==0)
{
dfs(tx,ty);
}
}
}
void init()//初始化
{
for(int i=0;i<101;i++)
{
for(int j=0;j<101;j++)
{
book[i][j]=0;
}
}
}
int main()
{
while(1)
{
init();
ans=0;
scanf("%d%d",&n,&m);getchar();
if(m==0)break;
for(int i=1;i<=n;i++)//输入
{
for(int j=1;j<=m;j++)
{
scanf("%c",&a[i][j]);
}getchar();
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='@'&&book[i][j]==0)//未搜索才可以开始搜索
{
dfs(i,j);
ans++;//计数
}
}
}
cout<<ans<<endl;
}
}
https://vjudge.net/contest/547627#problem/D
分析题目可以知道,就是交叉组合,然后对半分开,继续交叉组合,模拟一下可以知道重复几次后会回到最初的模样,所以接下来的编织没有意义,可以直接判定失败。写俩个函数,一个死循环,不断的组合,对半分开,再和原串进行比较,和目标串进行比较
#include<stdio.h>
#include<string.h>
char temp[210];
int len;
char s1[105],s2[105],s3[210],s4[210];
void var()//编织字符串
{
int k=0;
for(int i=0;i<len;i++)
{
s4[k++]=s2[i];
s4[k++]=s1[i];
}
}
void fj()//分解字符串
{
for(int i=0;i<len;i++)
{
s1[i]=s4[i];
}
for(int i=len;i<2*len;i++)
{
s2[i-len]=s4[i];
}
}
int main()
{
int t;
scanf("%d",&t);
int k=1;
while(k<=t)
{
int n,ans=0;
scanf("%d",&n);getchar();
scanf("%s",s1);
scanf("%s",s2);
scanf("%s",s3);
strcpy(s4,s3);
len=strlen(s1);
while(1)
{
var();
if(ans==0)
{
strcpy(temp,s4);
}
fj();
ans++;
if(strcmp(s3,s4)==0)
{
printf("%d %d\n",k,ans);
break;
}
if(strcmp(s4,temp)==0&&ans!=1)
{
printf("%d ",k);
printf("-1\n");
break;
}
}
k++;
}
}
https://vjudge.net/contest/547627#problem/G
最短时间首先想到bfs,但这里可以俩人一起走,这里贪心不可取,俩人都最近的地方不一定是同一个地方,可以2人bfs完整个地图,存储好每个终点的步数,最后遍历所有终点,比较和的大小,取最小值。
#include<stdio.h>
#include<string.h>
char a[205][205];
int book[205][205][2];
int nex[4][2]={{0,1},{0,-1},{1,0},{-1,0}},cnt;
int n,m;
struct node
{
int x,y;
}kfc[205*205];
struct node1
{
int x,y;
int step;
}que[205*205];
int min(int x,int y)
{
return x>y?y:x;
}
void bfs(int sx,int sy,int z)
{
int head=1,tail=1;
que[tail].x=sx;
que[tail].y=sy;
que[tail].step=0;
tail++;
while(head<tail)
{
for(int i=0;i<4;i++)
{
int tx=que[head].x+nex[i][0];
int ty=que[head].y+nex[i][1];
if(tx>=0&&ty>=0&&tx<n&&ty<m&&book[tx][ty][z]==0&&a[tx][ty]!='#')
{
book[tx][ty][z]=book[que[head].x][que[head].y][z]+1;
que[tail].x=tx;
que[tail].y=ty;
que[tail].step=que[head].step+1;
tail++;
}
}
head++;
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
getchar();
cnt=0;
int sx,sy,ex,ey;
memset(book,0,sizeof(book));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%c",&a[i][j]);
if(a[i][j]=='@')
{
kfc[cnt].x=i;
kfc[cnt++].y=j;
}
if(a[i][j]=='Y')
{
sx=i;
sy=j;
}
if(a[i][j]=='M')
{
ex=i;
ey=j;
}
}getchar();
}
bfs(sx,sy,0);
bfs(ex,ey,1);
int ans=99999999;
for(int i=0;i<cnt;i++)
{
if(book[kfc[i].x][kfc[i].y][0]!=0&&book[kfc[i].x][kfc[i].y][1]!=0)
{
ans=min(ans,book[kfc[i].x][kfc[i].y][0]+book[kfc[i].x][kfc[i].y][1]);
}
}
printf("%d\n",ans*11);
}
}
力扣刷题复习任务完成
![](https://img-blog.csdnimg.cn/img_convert/9de150ac8eba42b85ad1b8f767e322ef.png)
力扣刷题不仅温习了一下算法,也学到了一些知识,
双指针的思路:设置数组头一个指针,数组尾一个指针,和大于目标数则尾指针--,和小于目标数则头指针++。(这个思路当时想不到,知道是双指针,但是还是想不到)
另一个思路,求和,可以先遍历数组,确定一个数,然后二分查找该数的右边的数
小结:
vj俩天四道题的任务没有完成,还差一道(未改进好)(问题所在:用dfs爆搜不大熟悉,需要加强);
力扣算法复习任务完成
java学习时间过少