SZU 2015 Winter Training Day#2

10 篇文章 0 订阅
7 篇文章 0 订阅

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;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值