搜索,二分题

1搜索回溯问题
Q - 真·水题 OpenJ_Bailian - 4127
定义一个二维数组:

int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
题目简述:迷宫问题给出起点到终点 求最短路径的每步坐标
题目解析:广搜+回溯
代码如下:

#include<stdio.h>
int i,j,head,tail,a[101][101],book[101][101]; 
struct map
{
    int x;
    int y;
    int c;
}que[101];
print(int head)
{
    while(que[head].c!=-1)
    {
    	print(que[head].c);
        printf("(%d, %d)\n",que[head].x,que[head].y);
        return 0;
    }
    printf("(0, 0)\n");
}
int main()
{
	int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
    struct map ass;
    for(i=0;i<5;i++)    
        for(j=0;j<5;j++)
            scanf("%d",&a[i][j]);
    head=0,tail=1;
    que[0].x=0;
    que[0].y=0;
    que[0].c=-1;
    while(head<tail)
    {
       if(que[head].x==4&&que[head].y==4)
       {
            print(head);
            break;
       }
       for(i=0;i<4;i++)
       {
           ass.x=que[head].x+dir[i][0];
           ass.y=que[head].y+dir[i][1];
           ass.c=head;//用于回溯
           if(ass.x<0||ass.x>5||ass.y<0||ass.y>5)
           continue;
           if(book[ass.x][ass.y]==0&&a[ass.x][ass.y]==0)
           {    
		   		book[ass.x][ass.y]=1;
                que[tail]=ass;//结构体可以整体赋值
                tail++;
           }
       }
       head++;
	}
}

2搜索
A - 平行宇宙 POJ - 1426
在2100年科学家发现了平行宇宙,但是新发现的Earth2的世界中所有数字都是由0和1组成的十进制数,如果从我们的世界穿越到Earth2,数字将发生一些变化,例如:一个正整数n,将被转化为n的一个非零的倍数m,这个m应当符合Earth2的数字规则。你可以假定n不大于200且m不多于100位。
提示:本题采用Special Judge,你无需输出所有符合条件的m,你只需要输出任一符合条件的m即可。

Input
输入包含多组数据,每组数据仅一行,只包含一个正整数n,n==0时输入结束 (1 <= n <= 200).

Output
对于输入的每组n,都输出任一符合条件的m。即使有多个符合条件的m,你也只需要输出一个即可。
(已知long long范围内存在表示数据中所有的m

Sample Input
2
6
19
0

Sample Output
10
100100100100100100
111111111111111111
题目简述:找一个由1和0组成的并且是所给数据的倍数的数
题目解析:广搜即可,dfs(ans10)和dfs(ans10+1)注意当找到一个符合的数就需要退出 flag的作用就是一层层结束
代码如下

#include<stdio.h>
int n;
int flag=0;
int dfs(long long int ans,int cnt)
{
    if(flag==1)
    return 0;
    if(ans%n==0)
    {
        printf("%lld\n",ans);
        flag=1;
        return 0;
    }
    if(cnt>=19)return 0;
    dfs(ans*10,cnt+1);
    dfs(ans*10+1,cnt+1);
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)
        break;
        flag=0;
        dfs(1,1);
    }
}

3 搜索
B - 马走日 OpenJ_Bailian - 4123
马在中国象棋以日字形规则移动。

请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。

Input
第一行为整数T(T < 10),表示测试数据组数。
每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标n,m,x,y。(0<=x<=n-1,0<=y<=m-1, m < 10, n < 10)
Output
每组测试数据包含一行,为一个整数,表示马能遍历棋盘的途径总数,0为无法遍历一次。
Sample Input
1
5 4 0 0
Sample Output
32
题目简述:给出起点 问全部遍历棋盘上的点的路径个数
题目解析:dfs 统计步数 步数满足棋盘大小sum++ 一个点可遍历多次所以需要取消标记
代码如下

#include<stdio.h>
int vis[10][10],n,m,sum;
void dfs(int x,int y,int cnt)
{
	int dir[8][2]={{1,2},{1,-2},{-1,-2},{-1,2},{2,1},{2,-1},{-2,1},{-2,-1}};  
	if(cnt>=n*m)		
		sum++;
	for(int i=0;i<8;i++)
	{
		int tx=x+dir[i][0];
		int ty=y+dir[i][1];
		if(tx>=0&&tx<n&&ty>=0&&ty<m&&vis[tx][ty]==0)	 
		{
			vis[tx][ty]=1;
			dfs(tx,ty,cnt+1);
			vis[tx][ty]=0;
		}
	}
}
 
int main()
{
	int t,x,y,i,j;
	scanf("%d",&t);
	while(t--)
	{
		for(i=0;i<10;i++)
			for(j=0;j<10;j++)
				vis[i][j]=0;			
		scanf("%d %d %d %d",&n,&m,&x,&y);
		vis[x][y]=1;				
		sum=0;
		dfs(x,y,1);				
		printf("%d\n",sum);
	}
	return 0;
}

4 搜索
C - 棋盘问题 POJ - 1321
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1
#.
.#
4 4
…#
…#.
.#…
#…
-1 -1
Sample Output
2
1
题目简述:求将棋子放不同列 不同行的方案数
题目解析:深搜 搜索下一行 cnt记录所走行数 当cnt达到棋盘的行数 sum++
代码如下

#include<stdio.h>
char c[9][9];
int vis[101],n,k,sum;
void dfs(int x,int cnt)
{
    if(k==cnt)
    {
        sum++;
        return ;
    }
    for(int i=x;i<n;i++)//注意i是从x开始遍历的
        for(int j=0;j<n;j++)
    {
        if(c[i][j]=='#'&&vis[j]==0)
	    {   vis[j]=1;
	        dfs(i+1,cnt+1);
	        vis[j]=0;
	    } 
    }
}
int main()
{
    while(scanf("%d%d",&n,&k))
    {
        if(n==-1&&k==-1)
            break;
        for(int i=0;i<n;i++)
            scanf("%s",&c[i]);
        sum=0;
        for(int i=0;i<101;i++)
        	vis[i]=0;
        dfs(0,0);
        printf("%d\n",sum);
    }
    return 0;
}

5 二分
POJ - 2456
在彩虹岛的湖里有C只鹅,所以ww建造了一座包括N个隔间的畜栏,分别在坐标轴上的x1…xN位置,但这些鹅都彼此看不惯对方,为了防止他们互相伤害,所以不能把几只鹅放在一个隔间里,而且还应该使两只鹅之间的最小距离尽可能的大,可ww思考了好久,都不知道这个最大的最小距离是多少,你能不能帮帮他呢?
数据范围:2<=N<=100000, 0<=xi<=1000000000, 2<=C<=N
Input
有多组测试数据,以EOF结束。
第一行包含两个整数N和C
后面接着有N行,分别表示xi的位置。
Output
每组测试数据输出一个整数,即题目中所说的最大的最小值。
Sample Input
5 3
1
2
8
4
9
Sample Output
3
题目简述:求最小距离最大化
题目解析:二分确定距离 check函数判断是否符合题意

#include<stdio.h>
#include<algorithm>
using namespace std;
long long int n,c;
long long int a[100001],i;
int fact(long long int d)
{
    int ass=a[0];
    int sum=1;
    for(i=1;i<n;i++)
    {
        if(a[i]-ass>=d)
        {
            sum++;
            ass=a[i];
        }
    }
    if(sum>=c)
    return 1;
    return 0;
}
int main()
{
    long long int min,max,mid;
    while(scanf("%lld %lld",&n,&c)!=EOF)
    {   for(i=0;i<n;i++)
        scanf("%lld",&a[i]);
        sort(a,a+n);
        max=a[n-1]-a[0];
        min=0;
        while(max-min>1)
        {
            mid=(max+min)/2;
            if(fact(mid))
            min=mid;
            else
            max=mid;
        }
        printf("%lld\n",min);
    }
}

6二分
HDU - 2899
Now, here is a fuction:
F(x) = 6 * x7+8*x6+7x3+5*x2-yx (0 <= x <=100)
Can you find the minimum value when x is between 0 and 100.
Input
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has only one real numbers Y.(0 < Y <1e10)
Output
Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100.
Sample Input
2
100
200
Sample Output
-74.4291
-178.8534
题目简述:给出y的值以及x的范围(1到100)求方程值的最小值
题目解析:找方程值最小对应的x是关键 通过二分找导函数等于0 可以找出这个x
代码如下

#include<stdio.h>
#include<math.h> 
double y;
double ans(double i)
{
    return  6*pow(i,7)+8*pow(i,6)+7*pow(i,3)+5*i*i-y*i;

}
double fact(double i)
{
    return 42*pow(i,6)+48*pow(i,5)+21*i*i+10*i-y;
}
int main()
{
    double left,right,mid;
    int x;
    scanf("%d",&x);
    while(x--)
    {
        scanf("%lf",&y);
        left=0.0,right=100.0;
        while(right-left>1e-7)
        {
        	mid=(right+left)/2;
            if(fact(mid)<0)
            left=mid;
            else
            right=mid;
        }
        printf("%0.4lf\n",ans(mid));
    }
}

7搜索
OpenJ_Bailian - 2816

有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
Input
包括多个数据集合。每个数据集合的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下
1)‘.’:黑色的瓷砖;
2)‘#’:白色的瓷砖;
3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
当在一行中读入的是两个零时,表示输入结束。
Output
对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。
Sample Input
6 9
…#.
…#





#@…#
.#…#.
0 0
Sample Output
45
题目简述:给出起点求遍历迷宫的最大步数
题目解析:典型dfs
下面这个代码没有a过 显示wrong answer 用例可以过 自己实在没找出错哪了 哪位大佬如果能看出来还请指点指点

#include<stdio.h>
int cnt=0,i,j;
int n,m;
int book[101][101];
char map[101][101];
void dfs(int x,int y)
{
	cnt++;
	book[x][y]=1;
	int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
	for(int k=0;k<4;k++)
	{
		int tx=x+dir[k][0];
		int ty=y+dir[k][1];
		if(tx<0||ty<0||tx>m||ty>n)
		continue;
		if(book[tx][ty]==0&&map[tx][ty]=='.')
		{
			
			dfs(tx,ty);
		}
		
	}
}
int main()
{
	while(scanf("%d %d",&m,&n)!=EOF) 
	{
		cnt=0;
		if(m==0&&n==0)
		return 0;
		for(i=0;i<n;i++)
			scanf("%s",map[i]);
		for(i=0;i<n;i++)
			for(j=0;j<m;j++)
				if(map[i][j]=='@')
				{
					//printf("%d %d",i,j);
				
					dfs(i,j);
					break;
				}
			printf("%d\n",cnt);
	for(i=0;i<101;i++)
		for(j=0;j<101;j++)
			book[i][j]=0;
	} 
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值