SZU 2015 Winter Training Day#2

本文解析了四个经典算法问题,包括N皇后问题、排列问题、迷宫最短路径问题及液体分配问题,通过示例代码详细介绍了如何使用递归和广度优先搜索等算法解决这些问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A - N皇后问题

Time Limit:1000MS     MemoryLimit:32768KB     64bit IO Format:%I64d& %I64u

Submit Status

Description

N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。 
你的任务是,对于给定的N,求出有多少种合法的放置方法。 

 

Input

共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。

 

Output

共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。

 

Sample Input

 1

8

5

0

 

Sample Output

 1

92

10

 

程序:
#include <iostream>
using namespace std;

bool place(int [],int);

int main()
{
	int a[15]={0},b[15]={0},k,n,sum;

	for (n=1;n<11;n++)
	{
		sum=0;

		k=1;
		a[k]=0;

		while (k)
		{
			a[k]++;
			while (a[k]<=n && !place(a,k)) a[k]++;
			if (a[k]>n) k--;
			else if (k==n)
				sum++;
			else 
			{
				k++;
				a[k]=0;
			}
		}

		b[n]=sum;
	}

	while (1)
	{
		scanf("%d",&n);
		if (!n) break;

		printf("%d\n",b[n]);
	}

	return 0;
}

bool place(int a[],int k)
{
	int i;

	for (i=1;i<k;i++)
		if (a[i]==a[k] || abs(a[i]-a[k])==abs(i-k))
			return false;

	return true;
}


B - 排列2

Time Limit:1000MS     MemoryLimit:32768KB     64bit IO Format:%I64d& %I64u

Submit Status

Description

Ray又对数字的列产生了兴趣: 
现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数。 

 

Input

每组数据占一行,代表四张卡片上的数字(0<=数字<=9),如果四张卡片都是0,则输入结束。 

 

Output

对每组卡片按从小到大的顺序输出所有能由这四张卡片组成的4位数,千位数字相同的在同一行,同一行中每个四位数间用空格分隔。 
每组输出数据间空一行,最后一组数据后面没有空行。 

 

Sample Input

 1 2 3 4

1 1 2 3

0 1 2 3

0 0 0 0

 

Sample Output

 1234 1243 1324 1342 1423 1432

2134 21432314 2341 2413 2431

3124 31423214 3241 3412 3421

4123 41324213 4231 4312 4321

 

1123 11321213 1231 1312 1321

2113 21312311

3112 31213211

 

1023 10321203 1230 1302 1320

2013 20312103 2130 2301 2310

3012 30213102 3120 3201 3210

 

程序:
#include <iostream>
#include <algorithm>
using namespace std;

bool place(int [],int);

int main()
{
	int a[10]={0},b[10]={0},k,n,sum,i,t,last,num[10]={0},kase=0;
	bool flag;

	while (1)
	{
		flag=false;
		for (i=1;i<5;i++)
		{
			scanf("%d",&num[i]);
			if (num[i]) flag=true;
		}
		if (!flag) break;

		if (kase) printf("\n");
		kase++;

		sort(num+1,num+5);

		last=0;
		t=0;
		k=1;
		a[k]=0;

		while (k)
		{
			a[k]++;
			while (k==1 && num[a[k]]==last)
				a[k]++;

			while (a[k]<=4 && !place(a,k)) a[k]++;
			if (a[k]>4) k--;
			else if (k==4)
			{
				t++;
				sum=0;
				for (i=1;i<=4;i++)
					sum=sum*10+num[a[i]];
				b[t]=sum;
				t%=6;
				if (!t)
				{
					sort(b+1,b+6);
					printf("%d",b[1]);
					for (i=2;i<=6;i++)
						if (b[i]!=b[i-1]) printf(" %d",b[i]);
					printf("\n");
					last=num[a[1]];
				}
			}
			else 
			{
				k++;
				a[k]=0;
			}
		}
	}

	return 0;
}

bool place(int a[],int k)
{
	int i;

	for (i=1;i<k;i++)
		if (a[i]==a[k])
			return false;

	return true;
}

C - 迷宫问题

Time Limit:1000MS     MemoryLimit:65536KB     64bit IO Format:%I64d& %I64u

Submit Status

Description

定义一个二维数组: 


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 <iostream>
#include <queue>
using namespace std;

bool b[10][10];
int len[100],m;

struct pos
{
	int x,y,f;
} a[100][100],d[100];

void bfs(int);

int main()
{
	int i,j,c;

	memset(len,0,sizeof(len));
	memset(b,false,sizeof(b));
	b[1][1]=true;
	len[1]=1;
	a[1][1].f=0;
	a[1][1].x=1;
	a[1][1].y=1;

	for (i=0;i<=6;i++)
		b[0][i]=b[i][0]=b[6][i]=b[i][6]=true;
	
	for (i=1;i<=5;i++)
		for (j=1;j<=5;j++)
		{
			scanf("%d",&c);
			if (c) b[i][j]=true;
		}

	bfs(1);

	for (i=m-1;i>=0;i--)
		printf("(%d, %d)\n",d[i].x-1,d[i].y-1);

	return 0;
}

void bfs(int n)
{
	int i,j,k,l;

	j=1;

	for (i=1;i<=len[n];i++)
	{
		if (a[n][i].x==5 && a[n][i].y==5)
		{
			l=i;
			m=0;
			for (k=n;k>=1;k--)
			{
				d[m++]=a[k][l];
				l=a[k][l].f;
			}
			return;
		}
		if (!b[a[n][i].x-1][a[n][i].y])
		{
			b[a[n][i].x-1][a[n][i].y]=true;
			a[n+1][j].f=i;
			a[n+1][j].x=a[n][i].x-1;
			a[n+1][j].y=a[n][i].y;
			j++;
		}
		if (!b[a[n][i].x+1][a[n][i].y])
		{
			b[a[n][i].x+1][a[n][i].y]=true;
			a[n+1][j].f=i;
			a[n+1][j].x=a[n][i].x+1;
			a[n+1][j].y=a[n][i].y;
			j++;
		}
		if (!b[a[n][i].x][a[n][i].y-1])
		{
			b[a[n][i].x][a[n][i].y-1]=true;
			a[n+1][j].f=i;
			a[n+1][j].x=a[n][i].x;
			a[n+1][j].y=a[n][i].y-1;
			j++;
		}
		if (!b[a[n][i].x][a[n][i].y+1])
		{
			b[a[n][i].x][a[n][i].y+1]=true;
			a[n+1][j].f=i;
			a[n+1][j].x=a[n][i].x;
			a[n+1][j].y=a[n][i].y+1;
			j++;
		}
	}
	len[n+1]=j-1;
	bfs(n+1);
}
 

D - 非常可乐

Time Limit:1000MS     MemoryLimit:32768KB     64bit IO Format:%I64d& %I64u

Submit Status

Description

大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N毫升和M毫升可乐的体积为SS<101)毫升 (正好装满一瓶),它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M101S0N0M0)。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"

 

Input

三个整数 : S可乐的体积 , N M是两个杯子的容量,以"0 0 0"结束。

 

Output

如果能平分的话请输出最少要倒的次数,否则输出"NO"

 

Sample Input

 7 4 3

4 1 3

0 0 0

 

Sample Output

 NO

<pre name="code" class="cpp">程序:
#include <iostream>
#include <queue>
using namespace std;

int s,n,m;

struct coke
{
	int s,n,m,step;
};

bool check(coke);
int bfs();

int main()
{
	int step;

	while (scanf("%d%d%d",&s,&n,&m) && s+n+m)
	{
		if (s%2)
		{
			printf("NO\n");
			continue;
		}
		step=bfs();
		if (step) printf("%d\n",step);
		else
			printf("NO\n");
	}

	return 0;
}

bool check(coke temp)
{
	int s1,n1,m1;
	s1=temp.s;
	n1=temp.n;
	m1=temp.m;

	if (s1==n1 && !m1) return true;
	if (m1==n1 && !s1) return true;
	if (s1==m1 && !n1) return true;

	return false;
}

int bfs()
{
	bool vis[101][101][101];
	coke temp,shift;
	queue<coke> split;

	memset(vis,false,sizeof(vis));

	temp.s=s;
	temp.n=temp.m=temp.step=0;
	vis[s][0][0]=true;
	split.push(temp);
	
	while (!split.empty())
	{
		temp=split.front();
		split.pop();

		if (check(temp))
			return temp.step;

		//s to n,m
		if (temp.s)
		{
			if (temp.s>n-temp.n)
			{
				shift.s=temp.s-(n-temp.n);
				shift.n=n;
				shift.m=temp.m;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}
			else
			{
				shift.s=0;
				shift.n=temp.n+temp.s;
				shift.m=temp.m;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}

			if (temp.s>m-temp.m)
			{
				shift.s=temp.s-(m-temp.m);
				shift.n=temp.n;
				shift.m=m;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}
			else
			{
				shift.s=0;
				shift.n=temp.n;
				shift.m=temp.m+temp.s;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}
		}


		//n to s,m
		if (temp.n)
		{
			if (temp.n>s-temp.s)
			{
				shift.s=s;
				shift.n=temp.n-(s-temp.s);
				shift.m=temp.m;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}
			else
			{
				shift.s=temp.s+temp.n;
				shift.n=0;
				shift.m=temp.m;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}

			if (temp.n>m-temp.m)
			{
				shift.s=temp.s;
				shift.n=temp.n-(m-temp.m);
				shift.m=m;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}
			else
			{
				shift.s=temp.s;
				shift.n=0;
				shift.m=temp.m+temp.n;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}
		}


		//m to s,n
		if (temp.m)
		{
			if (temp.m>s-temp.s)
			{
				shift.s=s;
				shift.n=temp.n;
				shift.m=temp.m-(s-temp.s);
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}
			else
			{
				shift.s=temp.s+temp.m;
				shift.n=temp.n;
				shift.m=0;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}

			if (temp.m>n-temp.n)
			{
				shift.s=temp.s;
				shift.n=n;
				shift.m=temp.m-(n-temp.n);
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}
			else
			{
				shift.s=temp.s;
				shift.n=temp.n+temp.m;
				shift.m=0;
				shift.step=temp.step+1;
				if (!vis[shift.s][shift.n][shift.m])
				{
					vis[shift.s][shift.n][shift.m]=true;
					split.push(shift);
				}
			}
		}

	}
	return 0;
}
 
### 深圳大学数字电路实验相关资料概述 深圳大学数字电路课程的实验报告及相关指导文档是学生学习和实践数字电路设计的重要资源。以下是根据已有引用内容整理的相关信息: #### 实验五:彩灯流水电路设计 彩灯流水电路的设计与实现是一个典型的数字电路实验项目,旨在帮助学生理解时序逻辑电路的工作原理及其应用[^1]。实验报告详细记录了实验目的、实验原理、实验步骤及结果分析,为学生提供了从理论到实践的完整学习路径。例如,通过使用计数器和移位寄存器等元件,可以实现彩灯的顺序点亮效果[^5]。 #### 实验一:门电路逻辑功能测试 门电路逻辑功能的测试是数字电路学习的基础环节。实验报告不仅涵盖了基本的逻辑门(如与门、或门、非门)的功能测试,还通过实际操作加深了学生对布尔代数的理解[^2]。这份报告对于初学者掌握数字电路的基本逻辑运算具有重要意义。 #### 实验四:集成触发器功能测试及转换 集成触发器的功能测试及转换实验进一步拓展了学生的知识范围。触发器作为时序逻辑电路的核心元件,其工作原理和应用是数字电路学习中的重点内容之一[^3]。实验报告中详细描述了不同类型触发器(如D触发器、JK触发器)的功能测试方法及其相互转换的过程。 #### 实验六:555定时器电路设计与应用 555定时器是一种广泛应用于脉冲产生、定时控制等场景的集成电路。实验报告深入探讨了555定时器的工作原理及其在多谐振荡器、单稳态触发器等电路中的应用[^4]。通过本实验,学生可以掌握如何利用555定时器设计各种实用电路。 ### 使用建议 为了充分利用上述实验报告及相关指导文档,建议按照以下方式进行操作: 1. 下载并打开对应的实验报告文档。 2. 仔细阅读实验目的、实验原理、实验步骤及结果分析部分。 3. 在实验室环境中按照实验步骤进行实际操作。 4. 注意实验过程中可能遇到的问题,并参考报告中的分析部分解决。 ```python # 示例代码:简单的555定时器多谐振荡器仿真 import numpy as np import matplotlib.pyplot as plt # 参数设置 R1 = 1000 # 电阻值1 (欧姆) R2 = 2000 # 电阻值2 (欧姆) C = 0.001 # 电容值 (法拉) # 计算频率 f = 1 / (1.44 * (R1 + 2 * R2) * C) # 时间轴 t = np.linspace(0, 0.1, 1000) # 输出波形 output = np.where((t % (1 / f)) < (1 / (2 * f)), 5, 0) # 绘图 plt.plot(t, output) plt.title("555 Timer Multivibrator Output") plt.xlabel("Time (s)") plt.ylabel("Voltage (V)") plt.grid(True) plt.show() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值