项目:今天学了bfs(宽搜索)敲了俩个代码
思考今天启航开的新题组《栈》组的判断栈的合法性,大概有相关思路,明天打出来。
继续看《啊哈算法》的搜索这章(明天估计就可以看完,今天看到了油管地图那里。
做了力扣的链表题目(简单题目:逆转链表)
学习效果展示
解救小哈
#include<stdio.h>
struct note
{
int x;//横坐标
int y;//纵坐标
int f;//路径,即是父亲
int s;//步数
};//地图不大于2501,队列扩展不过2500个
main()
{
struct note que[2501];
int a[51][51]={0},book[51][51]={0};
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//走的方向一般情况下book就是标记
int head,tail;
int i,j,k,n,m,startx,starty,p,q,tx,ty,flag;
scanf("%d %d",&n,&m);//输入行,列
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);//赋值
scanf("%d %d %d %d",&startx,&starty,&p,&q);//出生地(x,y),目标地
head=1;
tail=1;
que[tail].x=startx;
que[tail].y=starty;
que[tail].f=0;//无父亲
que[tail].s=0;//还无步骤
tail++;//队列加1
book[startx][starty]=1;//标记,好马不吃回头草
flag=0;//标记是否到了终点
while(head<tail)//只要队列不是空,就继续做
{
for(k=0;k<=3;k++)//四个方向
{
tx=next[k][0]+que[head].x;//x走了!
ty=next[k][1]+que[head].y;//y先生也走了!!
if(tx<1||tx>n||ty<1||ty>n)//注意边界,要不然就是穿过去
continue;
if(a[tx][ty]==0&&book[tx][ty]==0)//我a代表这不是障碍物,book代表我还没有重复走
{
que[tail].x=tx;//入列
que[tail].y=ty;//入列
book[tx][ty]=1;//我走过了,我以后不走了
que[tail].f=head;//我父亲是谁
que[tail].s=que[head].s+1;//我走了一步。步骤加1
tail++;
}
if(tx==p&&ty==q)//到了目的地
{
flag=1;//我标记
break;//退出
}
}
if(flag)//如果到了,我就退出,没有到我就继续走
break;
head++;//这里一定要head++,完成一次扩展,然后继续扩展新的(敲黑板)。
}
printf("%d",que[tail-1].s);//输出步骤
return 0;
}
这里有一个我刚开始错误的一个地方(可能是我以习惯性的dfs打了)
就是
tx=next[k][0]+que[head].x;
ty=next[k][1]+que[head].y;
我打错了,然后就是变成了
tx+=next[k][0];
ty+=next[k][1];
这里故意不加粗,是错误的。但是你可以去理解下为什么那个要写成黑体加粗,而这个错误代码不行。(可以思考下)
宝藏探险
#include<stdio.h>
struct note
{
int x;
int y;
};
main()
{
struct note que[2501];
int head,tail;
int a[51][51];
int book[51][51]={0};
int i,j,k,sum,max=0,mx,my,n,m,startx,starty,tx,ty;
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
scanf("%d %d %d %d",&n,&m,&startx,&starty);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
head=1;
tail=1;
que[tail].x=startx;//初始x
que[tail].y=starty;//初始y
tail++;
book[startx][starty]=1;//走过来初始点
sum=1;
while(head<tail)//队列不为空
{
for(int k=0;k<=3;k++)//四个方向,上下左右baba(x)
{
tx=que[head].x+next[k][0];//移动x
ty=que[head].y+next[k][1];//移动y
if(tx<1||ty<1||tx>n||ty>m)//我不让你越界,嘻嘻嘻
continue;
if(a[tx][ty]>0&&book[tx][ty]==0)//我只要不是0,就是陆地,我就可以进行移动,
//book还是不走回头路
{
sum++;//统计路地
book[tx][ty]=1;//走过了
que[tail].x=tx;
que[tail].y=ty;
tail++;
}
}
head++;//!!!敲黑板,记得head++,进行下一次深度搜索
}
printf("%d",sum);//输出
}
其实思路和解救小哈差不多,都是慢慢拓展。
结构体
逆转链表
力扣(题目链接,简单难度)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* p=NULL;
struct ListNode* temp;
struct ListNode* last=head;
while(last)
{
temp=last->next;
last->next=p;
p=last;
last=temp;
}
return p;
}
这个我不好打注释,我就画图,给人家看吧
(ps:一般没有用链表做题目,或者敲代码,就算知道理论,上机还是没有感觉,所以理论只是基础,去敲才是王道。)
1
2
3
整理下
4
整理
杂思
题目:已知自然数 1 1 1 , 2 2 2 , ⋯ \cdots ⋯ , N N N ( 1 ≤ N ≤ 1 0 0 1\N\100 1 ≤ N ≤ 100 )依次入栈,请问序列 C 1 C_1 Ç 1 , C 2 C_2 Ç 2 , ⋯ \cdots ⋯ , C N C_N C N 是否为合法的出栈序列。
输入格式
输入包含多组测试数据。
每组测试数据的第一行为整数 N N N ( 1 ≤ N ≤ 1 0 0 1\N\100 1 ≤ N ≤ 100 ),当 N = 0 N=0 N = 0 时,输入结束。
第二行为 N N N 个正整数,以空格隔开,为出栈序列。
输出格式
对于每组输入,输出结果为一行字符串。
如给出的序列是合法的出栈序列,则输出 "Yes"
,否则输出 "No"
。
思想:我觉得真的就是恶心他妈给恶心开门——恶心到家了。呜呜呜,才接触栈才几天,那本书里面也没有多少。
就全部靠个人理解
可能思维混呜呜呜
这里·用到了了队列和栈
先让数进栈,然后拿队列首部与栈进行比较,不相等,第二个数进栈,栈顶再加1,然后通过队首比较,符合,队首下移到第二位,出栈,栈顶减1,继续比较,看栈顶和队首。如果为空栈了,先接着放数,然后比较,一旦有出现队首的值小于栈顶的值,那么就一定不符合栈的要求,