枯木逢春不再茂,年少且惜镜子边人
这周准备复习一下之前的内容,学习一下图,和树(简单的),然后学习一下java操作,然后做一些题.(想法很好)
1.先来说说学过的,栈和队列吧
栈 是先进后出
队列是 先进先出
写一个例子(队列!)吧
首先题目,一串数字,一个删除第二个放最后,然后第3个删除 第4个放最后,依次进行,然后输出删除的就是需要的东西,来看看吧
#include<stdio.h>
int main()
{
int q[102]={0,6,3,1,7,5,8,9,2,4},head,tail;
head=1;
tail=10;
while(head<tail)
{
printf("%d",q[head]);
head++;
q[tail]=q[head];
tail++;
head++;
}
return 0;
}
然后用结构体写一遍吧
#include<stdio.h>
struct que
{
int data[1000];
int head;
int tail;
};
int main()
{
struct que q;
int i;
que.tail=1;
que.head=1;
for(i=1;i<=9;i++)
{
scanf("%d",&q.data[tail]);
q.tail++;
}
whie(q.head<q.tail)
{
printf("%d",q.data[q.head]);
q.head++;
q.data[q.tail]=q.data[q.head];
q.tail++;
q.head++;
}
return 0;
}
基本操作,大家都可以看懂吧.
下来讲一下栈吧
栈的特例就是回文判断
多的不说了,直接看代码吧!
#include<stdio.h>
#include<string.h>
int main()
{
char a[101],s[101];
int i,len,mid,next,top;
gets(s);
len=strlen(s);
mid=len/2-1;
top=0;
for(i=0;i<=mid;i++)
a[++top]=s[i];
if(len%2==0)
next=mid+1;
else
next=mid+2;
for(i=next;i<len;i++)
{
if(s[i]!=a[top])
break;
top--;
}
if(top==0)
printf("yes");
else
printf("no");
return 0;
}
这样判断回文就很简单
看一下结构体中的栈吧
#include<stdio.h>
#include<string.h>
struct zhan
{
char s[101];
int top;
};
int mian()
{
int len,mid,next,i;
char a[101];
struct zhan f;
gets(a);
f.top=0;
len=strlen(a);
mid=mid/2-1;
for(i=0;i<=mid;i++)
f.s[++top]=a[i];
if(len/2==0)
next=mid+1;
else
next=mid+2
for(i=next;i<len;i++)
{
if(f.s[top]!=a[i])
break;
s.top--;
}
if(s.top==0)
printf("YES");
else
printf("no");
return 0;
}
史诗级大题《马拦过河卒》
棋盘上 AAA 点有一个过河卒,需要走到目标 BBB 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 CCC 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,AAA 点 (0,0)(0, 0)(0,0)、BBB 点 (n,m)(n, m)(n,m),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 AAA 点能够到达 BBB 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式 一行四个正整数,分别表示 BBB 点坐标和马的坐标。
输出格式 一个整数,表示所有的路径条数。
输入输出样例 输入 #1
复制
6 6 3 3
输出 #1
复制
6
说明/提示 对于 100%100 %100% 的数据,1≤n,m≤201 \le n, m \le 201≤n,m≤20,0≤0 \le0≤ 马的坐标 ≤20\le 20≤20。
#include<stdio.h>
long long dp[21][21]={1};
int next[2][9]={{0,-2,-1,1,2,2,1,-1,-2},{0,1,2,2,1,-1,-2,-2,-1}};
int book[21][21];
int main()
{
int i,j;
int bx,by,mx,my;
scanf("%d%d%d%d",&bx,&by,&mx,&my);
for(i=0;i<9;i++)
{
if(mx+next[0][i]>=0&&mx+next[0][i]<=bx&&my+next[1][i]>=0&&my+next[1][i]<=by)
book[mx+next[0][i]][my+next[1][i]]=1;
}
for(i=0;i<=bx;++i)
for(j=0;j<=by;++j)
{
if(i)
dp[i][j]+=dp[i-1][j];
if(j)
dp[i][j]+=dp[i][j-1];
dp[i][j]=dp[i][j]*(!book[i][j]);
}
printf("%lld",dp[bx][by]);
return 0;
}
递推公式就dp[i][j]这个点会有两条路,一个上面,一个左边,dp代表的是这个点有几条路经过,所以递推公式就 dp[i][j]=dp[i-1][j]+dp[i][j-1];
然后把马的那几个点标记,标记时,标记终点以内的点。这样就可以了,详细请看代码!
重磅大题
《高精乘法,高精加法》
例题: 阶乘
#include<stdio.h>
int max=101;
int a[202],b[202],n,x;
int main()
{
int i,j,z;
a[0]=b[0]=1;
scanf("%d",&n);
for(i=2;i<=n;i++)
{
for(j=0;j<=max;j++)//模拟阶乘,如果是大于二位,则是模拟乘法
b[j]=b[j]*i;
for(j=0;j<=max;j++)
{
if(b[j]>=10)//进位
{
b[j+1]+=b[j]/10;
b[j]=b[j]%10;
}
}
for(z=0;z<=max;z++)//高精加法
{
a[z]+=b[z];//累加的结果
if(a[z]>=10)//进位
{
a[z+1]+=a[z]/10;
a[z]%=10;
}
}
}
for(i=202;i>=0;i--)
if(a[i]!=0)
{
x=i;
break;
}
for(j=x;j>=0;j--)
printf("%d",a[j]);
printf("\n");
return 0;
}
这是我目前看到的最简单的高精算法了,很棒,如有大佬有更简单的,请给小弟指出,QQ:**********,谢谢大佬
相信大家都知道炸弹人游戏吧,今天用dfs和bfs来做一做
#include<stdio.h>
struct node
{
int x;
int y;
};
struct node que[401];
char a[20][21];
int book[20][21];
int getnum(int i,int j)
{
int sum=0,tx,ty;
tx=i;ty=j;
while(a[tx][ty]!='#')
{
if(a[tx][ty]=='G')
sum++;
tx--;
}
tx=i;ty=j;
while(a[tx][ty]!='#')
{
if(a[tx][ty]=='G')
sum++;
tx++;
}
tx=i;ty=j;
while(a[tx][ty]!='#')
{
if(a[tx][ty]=='G')
sum++;
ty--;
}
tx=i;ty=j;
while(a[tx][ty]!='#')
{
if(a[tx][ty]=='G')
sum++;
ty++;
}
return sum;
}
int main()
{
int i,head,tail,tx,ty,mx,my,max=0,startx,starty,m,n,k;
int next[4][2]={{0,1},{1,0},{0-1},{-1,0}};
int sum=0;
scanf("%d %d %d %d",&m,&n,&startx,&starty);
for(i=0;i<m;i++)
scanf("%s",a[i]);
head=1;
tail=1;
que[tail].x=startx;
que[tail].y=starty;
max=getnum(startx,starty);
tx=startx;
ty=starty;
book[tx][ty]=1;
tail++;
while(head<tail)
{
for(k=0;k<4;k++)
{
tx=que[head].x+next[k][0];
ty=que[head].y+next[k][1];
if(tx<0||tx>n-1||ty<0||ty>m-1)
continue;
if(a[tx][ty]=='.'&&book[tx][ty]==0)
{
book[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
tail++;
sum=getnum(tx,ty);
if(sum>max)
{
max=sum;
mx=tx;
my=ty;
}
}
}
head++;
}
printf("应该放在(%d,%d)处,消灭了%d个敌人",mx,my,max);
return 0;
}
getnum函数是统计在这个点周围一共有多少敌人,依次上下左右寻找敌人
其他的则就是普通的bfs
再来看看dfs如何解决这道题吧
#include<stdio.h>
char map[20][21];
int book[20][21];
int next[4][2]={{0,1},{1,0},{0-1},{-1,0}};
int tx,ty,max,sum,mx,my,n,m;
int getnum(int i,int j)
{
int sum=0,tx,ty;
tx=i;ty=j;
while(map[tx][ty]!='#')
{
if(map[tx][ty]=='G')
sum++;
tx--;
}
tx=i;ty=j;
while(map[tx][ty]!='#')
{
if(map[tx][ty]=='G')
sum++;
tx++;
}
tx=i;ty=j;
while(map[tx][ty]!='#')
{
if(map[tx][ty]=='G')
sum++;
ty--;
}
tx=i;ty=j;
while(map[tx][ty]!='#')
{
if(map[tx][ty]=='G')
sum++;
ty++;
}
return sum;
}
int dfs(int x,int y)
{
int k;
sum=getnum(x,y);
if(sum>max)
{
max=sum;
mx=x;
my=y;
}
for(k=0;k<4;k++)
{
tx=x+next[k][0];
ty=y+next[k][1];
if(tx<0||tx>n-1||ty<0||ty>m-1)
continue;
if(map[tx][ty]=='.'&&book[tx][ty]==0)
{
book[tx][ty]=1;
dfs(tx,ty);
}
}
return 0;
}
int main()
{
int i,startx,starty;
scanf("%d %d %d %d",&n,&m,&startx,&starty);
for(i=0;i<n;i++)
scanf("%s",map[i]);
max=getnum(startx,starty);
mx=startx;
my=starty;
dfs(startx,starty);
printf("应该放在(%d,%d)处,消灭了%d个敌人",mx,my,max);
}
dfs和bfs都可以解决这道题,宽搜是从一个点扩展出4个点然后依次计算4个点,然后继续搜索,dfs是一条路线,搜索不下去了然后就退回来,因为之前标记过,所以就不会算重复的点,感觉就是不撞南墙不回头的样子,更多请看代码
下面就来看一下,之前林某人讲过的判断面积吧
题目:一张地图中判断岛屿
话不多说看代码
#include<stdio.h>
struct node
{
int x;
int y;
};
int book[51][51];
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int main()
{
int i,j,m,n,startx,starty,tx,sum=0,ty,k;
struct node que[2501];
int a[51][51];
int head,tail;
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;
que[tail].y=starty;
book[startx][starty]=1;
sum=1;
tail++;
while(head<tail)
{
for(k=0;k<4;k++)
{
tx=que[head].x+next[k][0];
ty=que[head].y+next[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(a[tx][ty]!=0&&book[tx][ty]==0)
{
sum++;
book[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
tail++;
}
}
head++;
}
printf("%d\n",sum);
return 0;
}
这道题可以用BFS DFS都可以做,和传统的模板没什么太大区别,我们看看dfs吧
#include<stdio.h>
int a[51][51];
int book[51][51];
int n,m,tx,ty,sum;
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
void dfs(int x,int y)
{
int k;
for(k=0;k<4;k++)
{
tx=x+next[k][0];
ty=y+next[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(a[tx][ty]!=0&&book[tx][ty]==0)
{
sum++;
book[tx][ty]=1;
dfs(tx,ty);
}
}
return ;
}
int main()
{
int startx,starty,i,j;
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]);
sum=1;
book[startx][starty]=1;
dfs(startx,starty);
printf("%d\n",sum);
return 0;
}
这就是用dfs做的找地图题,很基础的,基本套用模板
接下来就是判断有一张地图里面有几张这样的岛屿了(这其中暗藏了染色),话不多说直接看代码吧!
#include<stdio.h>
int tx,ty,n,m,num=0;
int a[51][51];
int book[51][51];
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
void dfs(int x,int y,int color)
{
int k;
a[x][y]=color;
for(k=0;k<4;k++)
{
tx=x+next[k][0];
ty=y+next[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(a[tx][ty]!=0&&book[tx][ty]==0)
{
book[tx][ty]=1;
dfs(tx,ty,color);
}
}
return ;
}
int main()
{
int i,j,startx,starty;
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]);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
if(a[i][j]>0)
{
book[i][j]=1;
num--;
dfs(i,j,num);
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
printf("%3d",a[i][j]);
printf("\n");
}
printf("共有%d个岛屿",-num);
}
多加了个参数color,进行染色,主要部分还是搜索一个地图,
这就是染色问题
哎这周还是没有达到理想要求,但是搜索基本算入门,还有个水管工问题没有解决,放在下次周报吧。好的,谢谢各位大佬围观,下周见。