知识点
栈和队列
dfs
链表(还在学习中ing)
直接上题目:
其中要注意的是
多组输入要写成while(~scanf("%d",&n)&&n!=0)
不能写while(scanf("%d",&n)!=0)
代码实现:
#include <stdio.h>
#include<string.h>
int main()
{
int n,a[1001],b[1001],i,k,top;//a数组储存输入数据,b为栈
while(~scanf("%d",&n)&&n!=0)//注意这里不能写while(scanf("%d",&n)!=0)
{
memset(a,0,1001);
memset(b,0,1001);
while (~scanf("%d", &a[1]))///因为这里输入了a[1]
{
if (a[1] == 0)//对应题中:每行由n个1到n的整数组成
break; //直到某一行第一个数是0表示此输入块结束
for (i=2;i<=n;i++)///所以这里从i=2开始
scanf("%d",&a[i]);
k=1;top=1;//top为栈顶
for(i=1;i<=n;i++)
{
b[top]=i;
while(b[top]==a[k]&&top>0)///这里不太好理解,有时间手算过程
{
top--;
k++;
}
top++;
}
if(k>n) printf("Yes\n");
else printf("No\n");
}
printf("\n");
}
return 0;
}
下一题:
与上一题类似,我现在写的代码已经可以答案正确了可是时间超限了,暂时没想到更好的办法呜呜…
当前的代码:
///A与G类似
#include <stdio.h>
#include<string.h>
int fun(int a[],int n)
{
int b[101],i,k,top,max;
k=1;
top=1,max=0;//top为栈顶
for(i=1; i<=n; i++)
{
b[top]=i;
while(b[top]==a[k]&&top>0)///这里不太好理解,有时间手算过程
{
top--;
k++;
}
top++;
if(top>max)
max=top;
}
if(k>n) return max;
else return -1;
}
int main()
{
int n,i,a[101];
while(scanf("%d",&n))
{
for(i=1; i<=n; i++)
scanf("%d",&a[i]);
printf("%d\n",fun(a,n));
}
return 0;
}
///好不容易答案正确了又时间超限了我要哭了!!!!
接下来两题是搜索题
第一题卡了我好几天 最后在学长的帮助下发现是细节问题 已经搞定!
上题目:
上代码!(我用的是dfs)
#include<stdio.h>
int min=99999999;
int a[6][6],book[6][6],o=0,r;
struct road
{
int X[100];
int Y[100];///一直答案错误在了这里!!!!!!存路径的数组要开的大一些!!!!!!!
}lj;
struct road minval;
void dfs(int x,int y,int step)
{
int next[4][2]={{0,1},//向右走
{1,0},//向下走
{0,-1},//向左走
{-1,0}};//向上走
int tx,ty,k;
//先判断此时是否到达终点
if(x == 4 && y == 4)//终点坐标为(4,4)
{
//更新最小值
if(step<min)
{
//printf("我进来啦!\n");
min=step;
for(r=0;r<min;r++)//循环更新
{
minval.X[r]=lj.X[r];
minval.Y[r]=lj.Y[r];
//printf("更新为(%d,%d)\n",minval.X[r],minval.Y[r]);
}
//printf("====我是分界线====\n");
}
return;//注意这里的返回很重要
}
//枚举4种走法
for(k=0;k<=3;k++)
{
//计算下一个点的坐标
tx=x+next[k][0];
ty=y+next[k][1];
//判断是否越界
if(tx<0||tx>4||ty<0||ty>4)
continue;
//判断该点是否为障碍物或者已经在路径中
if(a[tx][ty] == 0&& book[tx][ty] == 0)
{
book[tx][ty]=1;//要走该点了,标记该点走过
lj.X[o]=tx;
lj.Y[o]=ty;
//printf("此时我的o=%d,坐标为(%d,%d)\n",o,lj.X[o],lj.Y[o]);///
o++;
dfs(tx,ty,step+1);
book[tx][ty]=0;
o--;//回溯
}
}
return;
}
int main()
{
int i,j;
//读入迷宫
for(i=0;i<5;i++)
for(j=0;j<5;j++)
scanf("%d",&a[i][j]);
//从起点(0,0)开始搜索
book[0][0]=1;//标记起点已经在路径中,防止后面重复走
//第一个参数是起点的x坐标,第二个参数是起点的y坐标,第三个参数的起始步数为0
dfs(0,0,0);
//printf("最短步数为%d\n",min);
//输出最短路径
printf("(0, 0)\n");//输出起点位置
for(r=0;r<min-1;r++)
printf("(%d, %d)\n",minval.X[r],minval.Y[r]);
printf("(4, 4)");
return 0;
}
貌似这道题用bfs也可以写,我试了一下,没写出来emmmm,下次再试试
然后在下一道题
是经典的n皇后问题
题目如下
解题过程:
我时间超限了,但是这道题的数据范围有限且不多我就用我时间超限的程序算出了所有情况,然后输入与输出一一对应另外写了个程序交上去过了……感觉这也可以说是一种方法吧emmm,等我水平更高了我看看我能不能不时间超限写出来!
以下是我时间超限的代码
#include<stdio.h>
#include<math.h>//int abs(int x) 返回 x 的绝对值
int rank[10],book[10];//book为标记数组
int n,num=0;
void dfs(int row)
{
if(row==n+1)//递归边界条件(当遍历到第n+1组时,说明已出一组结果)
{
num++;
return;
}
for(int i=1; i<=n; i++)//枚举每一行
{
if(book[i]==0)
{
int flag=1;
for(int j=1; j<row; j++)//枚举row之前的皇后
{
if(abs(row-j)==abs(i-rank[j]))
{
flag=0;
break;
}
}
if(flag)
{
rank[row]=i;//row列在i行
book[i]=1;
dfs(row+1);
book[i]=0;
}
}
}
}
int main()
{
while(scanf("%d",&n) && n!= 0)
{
num=0;
dfs(1);
printf("%d\n",num);
}
return 0;
}
然后以下是我通过的代码……
#include<stdio.h>
int main()
{
int n;
while(scanf("%d",&n) && n!= 0)
{
if(n == 1)
printf("1\n");
else if(n == 2)
printf("0\n");
else if(n == 3)
printf("0\n");
else if(n == 4)
printf("2\n");
else if(n == 5)
printf("10\n");
else if(n == 6)
printf("4\n");
else if(n == 7)
printf("40\n");
else if(n == 8)
printf("92\n");
else if(n == 9)
printf("352\n");
else if(n == 10)
printf("724\n");
}
return 0;
}
接下来就在学习链表
学习方式(书上关于链表的介绍看了,bilibili上找视频看,如果看完还不知道怎么写题,就先看看别人写链表题的代码,学习一下,然后再试着自己解决!)
因为我指针还不扎实,可以说是很不擅长了,本来想绕过指针用静态模拟链表的,但是学长说必须用指针链表,所以,还是逃不过,加油吧呜呜呜