第一次练习

题目

 

1.出栈序列统计

**********************************************************************源程序名:                           stack.???(C,CPP)                  *

*可执行文件名:                       stack.exe                        *

*输入文件名:                         stack.in                         *

*输出文件名:                         stack.out                        *

*********************************************************************

【问题描述】

       栈是常用的一种数据结构,有N个元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列。你已经知道栈的操作有两种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出。现在要使用这两种操作,由一系列操作序列可以得到一系列的输出序列。请你编程求出对于给定的N,计算并输出由等待进栈的序列1,2,……,N,经过一系列操作可能得到的输出序列总数。

【输入】

       一个整数N(1<=n<=15)。

【输出】

       一个整数,即可能输出序列的总数目。

【样例】

       stack.in

       3

 

       stack.out

       5

 代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#include <algorithm>
#define SWAP(x,y) {(x) = (x)^(y); (y)=(x)^(y); (x)=(x)^(y);}
#define MIN(x,y) (x<y?x:y)
#define INF 1e9
#define MAXN 100

int n, m;
	
int dfs(int num, int cnt){
	if(cnt>=n){
		m++;	return 1;
	}
	num++;
	dfs(num, cnt+1);
	while(num>0){
		dfs(num-1, cnt+1);
		num--;
	}	
	return 1;
}

int main(){
	freopen("stack.in", "r+", stdin);
	freopen("stack.out", "w+", stdout):
	int i;
	cin >> n;
	m = 0;
	dfs(0,1);
	cout << m;
	return 0;
}
 

2.走迷宫

**********************************************************************源程序名:                           maze.???(C,CPP)                  *

*可执行文件名:                       maze.exe                        *

*输入文件名:                         maze.in                         *

*输出文件名:                         maze.out                        *

*********************************************************************

【问题描述】

       有一个M*N格的迷宫(表示有M行、N列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这M*N个数据和起始点、结束点的位置。现在要你编程找出所有可行的道路,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出-1。

【输入】

       第一行是两个数M,N(1<m,n<15),接下来是M行N列由1和0组成的数据,最后两行是起始点和结束点的坐标信息。

【输出】

       一个整数,即能走通且不重复的道路的总数(没有可走通的道路时输出-1)。

【样例】

 maze.in

5 6

1 0 0 1 0 1

1 1 1 1 1 1

0 0 1 1 1 0

1 1 1 1 1 0

1 1 1 0 1 1

1 1

5 6

 

stack.out

12


代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#include <algorithm>
#define SWAP(x,y) {(x) = (x)^(y); (y)=(x)^(y); (x)=(x)^(y);}
#define MIN(x,y) (x<y?x:y)
#define INF 1e9
#define MAXN 100

int m, n;
int ans = 0;
int a[16][16];
int ex, ey;
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};

bool dfs(int x,int y){		
	int i;
	if(x == ex&&y == ey){
		ans++;
		return true;
	}
	
	for(i=0; i<4; ++i){
		int tx = x+dx[i];
		int ty = y+dy[i];
		if(tx<=0||tx>m||ty<=0||ty>n) return false;
		if(a[tx][ty] == 1){
			a[tx][ty] = 0;
			dfs(tx,ty);
			a[tx][ty] = 1;
		}
	}
	return false;
}

int main(){
	int i,j;
	int sx,sy;
	memset(a, 0 ,sizeof(a));
	scanf("%d%d", &m, &n);
	for(i=1; i<=m; ++i){
		for(j=1; j<=n; ++j){
			scanf("%d", &a[i][j]);
		}
	}
	
	scanf("%d%d", &sx, &sy);
	scanf("%d%d", &ex, &ey);
	
	ans = 0;
	dfs(sx,sy);
	printf("%d\n", ans);
	return 0;
}


 

3.组合的输出

**********************************************************************源程序名:                           compages.???(C,CPP)              *

*可执行文件名:                       compages.exe                    *

*输入文件名:                         compages.in                     *

*输出文件名:                         compages.out                    *

*********************************************************************

【问题描述】

       排列与组合是常用的数学方法,其中组合就是从N个元素中抽出R个元素(不分顺序且R<=N),我们可以简单地将N个元素理解为1,2,…,N,从中任取R个数。

       例如N=5,R=3,所有组合为:

       1 2 3 1 2 4  1 2 5  1 3 4 1 3 5  1 4 5  2 3 4 2 3 5  2 4 5  3 4 5

【输入】

       一行两个自然数N,R(1<N<21,1<=R<=N)。

【输出】

       所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素用一个空格隔开且行尾没有空格,所有的组合也按字典顺序。

【样例】

compages.in

5 3

 

compages.out

1 2 3

1 2 4

1 2 5

1 3 4

1 3 5

1 4 5

2 3 4

2 3 5

2 4 5

3 4 5

 

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#include <algorithm>
#define SWAP(x,y) {(x) = (x)^(y); (y)=(x)^(y); (x)=(x)^(y);}
#define MIN(x,y) (x<y?x:y)
#define INF 1e9
#define MAXN 20

int n,r;
int a[MAXN+5];

int dfs(int now, int len){
	if(len == r+1){
		for(int i =1; i<=r; ++i)
			printf("%d ", a[i]);
		printf("\n");
	}
	
	if(len>n)	return 1;
	
	for(int i=now; i<=n; ++i){
		a[len] = i;
		dfs(i+1, len+1);
	}
}

int main(){
	int i,j;
	
	scanf("%d%d", &n, &r);
	dfs(1,1);
	return 0;
}


 

4.关路灯

**********************************************************************源程序名:                          power.???(C,CPP)                 *

*可执行文件名:                       power.exe                       *

*输入文件名:                         power.in                        *

*输出文件名:                         power.out                       *

*********************************************************************

【问题描述】

       某个村庄在一条路线上安装了N盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少)。老张就住在这条路中间某一个路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯。

为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能最省电。他每天都是在天亮时首先关掉自己所在处位置的路灯,然后可以向左向右去关灯。开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大的一边,再回过头来关掉另一边的路灯,而事实并非如此,因为在关的过程中适当地掉头有可能会更省一些。

现在已知老张走的速度为1m/s,每个路灯的位置(是一个整数,即距路线起点的距离,单位:m)、功率(W),老张关灯所用的时间很短可以忽略不计。

请你为老张编一个程序来安排关灯的顺序,使从老张开始关灯时刻算起所有灯消耗电最少(灯关掉后便不再消耗电了)。

【输入】

       文件第一行是两个数字N(0<N<50,表示路灯的总数)和C(1<=C<=N 老张所处位置的路灯号);

       接下来N行,每行两个数据,表示第一盏灯到第N栈灯的位置和功率。

【输出】

       一个数据,即最少的功耗(单位:J,1J = 1W·S)。

【样例】

       power.in

       5 3

       2 10

       3 20

       5 20

       6 30

       8 10

 

       power.out

       270  {此时关灯顺序为3 4 2 1 5,不必输出这个关灯顺序}

 代码:
 

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
#define INF 1e9
#define MIN(x,y) (x<y?x:y)

struct Tnode{
	int pos,w;
}node[55];

int ans;
int n;
void dfs(int left, int right, int now, int len, int power, int step){
	//printf("len:%d(step:%d),left:%d right:%d now:%d power:%d\n", len, step, left, right, now, power);
	if(len == n){
		if(ans > power)
		ans = power;
		//printf("\n");
		return ;
	}
	
	if(left>0){
		int stepk = (step+node[now].pos-node[left].pos);
		int powerk = power + stepk*node[left].w;
		dfs(left-1, right, left, len+1, powerk, stepk);
	}
	
	if(right<=n){
		int stepk = step + node[right].pos - node[now].pos;
		int powerk = power + stepk*node[right].w;
		dfs(left, right+1, right, len+1, powerk, stepk);
	}
}

int main(){
	int c;
	scanf("%d%d", &n, &c);
	for(int i=1; i<=n; ++i){
		scanf("%d%d", &node[i].pos, &node[i].w);
	}
	
	ans = INF;
	dfs(c-1, c+1, c, 1, 0, 0);
	
	printf("%d\n", ans);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值