程序设计预算法二期末考试

1:大盗阿福

总时间限制:
1000ms
内存限制:
65536kB
描述

阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。

这条街上一共有 N 家店铺,每家店中都有一些现金。阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。

作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?

输入
输入的第一行是一个整数 T (T <= 50) ,表示一共有 T 组数据。
接下来的每组数据,第一行是一个整数 N (1 <= N <= 100, 000) ,表示一共有 N 家店铺。第二行是 N 个被空格分开的正整数,表示每一家店铺中的现金数量。每家店铺中的现金数量均不超过 1000 。
输出
对于每组数据,输出一行。该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。
样例输入
2
3
1 8 2
4
10 7 6 14
样例输出
8
24
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 100005
int t,n,ans;int f[N],a[N];
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);memset(f,0,sizeof(f));ans=0;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++){
            f[i]=a[i];
            f[i]=max(f[i-2]+a[i],f[i-3]+a[i]);
            ans=max(ans,f[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

2:马走日

总时间限制:
1000ms
内存限制:
1024kB
描述

马在中国象棋以日字形规则移动。

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

输入
第一行为整数T(T < 10),表示测试数据组数。
每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标n,m,x,y。(0<=x<=n-1,0<=y<=m-1, m < 10, n < 10)
输出
每组测试数据包含一行,为一个整数,表示马能遍历棋盘的途径总数,0为无法遍历一次。
样例输入
1
5 4 0 0
样例输出
32
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int sx[8]={1,1,-1,-1,2,2,-2,-2};
int sy[8]={2,-2,2,-2,1,-1,1,-1};
int t,n,m,x,y,ans;
bool b[20][20];
void dfs(int dep,int s,int t){
	if (dep==n*m){
		ans++; return;
	}
	for (int r=0;r<8;++r){
		int x=s+sx[r]; int y=t+sy[r];
		if (!b[x][y]&&x>0&&y>0&&x<=n&&y<=m){
			b[x][y]=true;
			dfs(dep+1,x,y);
			b[x][y]=false;
		}
	}
}
int main(){
	scanf("%d",&t);
	while (t--){
		scanf("%d%d",&n,&m);
		scanf("%d%d",&x,&y); ++x; ++y;
		memset(b,0,sizeof(b)); ans=0,b[x][y]=true; 
		dfs(1,x,y);
		printf("%d\n",ans);
	}
}

3:鸣人的影分身

总时间限制:
1000ms
内存限制:
65536kB
描述

在火影忍者的世界里,令敌人捉摸不透是非常关键的。我们的主角漩涡鸣人所拥有的一个招数——多重影分身之术——就是一个很好的例子。


影分身是由鸣人身体的查克拉能量制造的,使用的查克拉越多,制造出的影分身越强。

针对不同的作战情况,鸣人可以选择制造出各种强度的影分身,有的用来佯攻,有的用来发起致命一击。

那么问题来了,假设鸣人的查克拉能量为M,他影分身的个数为N,那么制造影分身时有多少种(用K表示)不同的分配方法?(影分身可以被分配到0点查克拉能量)

输入
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
输出
对输入的每组数据M和N,用一行输出相应的K。
样例输入
1
7 3
样例输出
8
#include<cstdio>
#include<iostream>
using namespace std;
#define N 12
int t,m,n;int f[N][N];             //f[i][j]表示把i分j个的方案数 
int main(){
    n=10,m=10;
    for(int i=0;i<=10;i++) f[0][i]=1;
    for(int i=1;i<=10;i++){
        for(int j=1;j<=10;j++){
            if(i>=j) f[i][j]=f[i][j-1]+f[i-j][j];
            else f[i][j]=f[i][i];
        }
    }
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&m,&n);
        printf("%d\n",f[m][n]);
    }
    return 0;
}

4:开餐馆

总时间限制:
1000ms
内存限制:
65536kB
描述

北大信息学院的同学小明毕业之后打算创业开餐馆.现在共有n 个地点可供选择。小明打算从中选择合适的位置开设一些餐馆。这 n 个地点排列在同一条直线上。我们用一个整数序列m1, m2, ... mn 来表示他们的相对位置。由于地段关系,开餐馆的利润会有所不同。我们用pi 表示在mi 处开餐馆的利润。为了避免自己的餐馆的内部竞争,餐馆之间的距离必须大于k。请你帮助小明选择一个总利润最大的方案。

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define LL long long


int main()
{
	int t,n,k;
	long long a[110],b[110],c[110];
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&k);
		for(int i=0;i<n;i++)
			scanf("%lld",&a[i]);
		for(int i=0;i<n;i++)
		{
			scanf("%lld",&b[i]);
			c[i]=b[i];	//记录每个位置的初始总利润 
		}		
		for(int i=1;i<n;i++)
		{
			for(int j=0;j<i;j++)
			{
				if(a[i]-a[j]>k)
				{
					c[i]=max(c[i],c[j]+b[i]);//每个位置的最大利润 
				}
				else
					continue;
			}
		}
		long long maxn=0;
		for(int i=0;i<n;i++)
		{
			maxn=max(maxn,c[i]);
		}
		printf("%lld\n",maxn);
	}
	return 0;
 } 


输入
标准的输入包含若干组测试数据。输入第一行是整数T (1 <= T <= 1000) ,表明有T组测试数据。紧接着有T组连续的测试。每组测试数据有3行,
第1行:地点总数 n (n < 100), 距离限制 k (k > 0 && k < 1000).
第2行:n 个地点的位置m1 , m2, ... mn ( 1000000 > mi > 0 且为整数,升序排列)
第3行:n 个地点的餐馆利润p1 , p2, ... pn ( 1000 > pi > 0 且为整数)
输出
对于每组测试数据可能的最大利润
样例输入
23 111 2 1510 2 303 161 2 1510 2 30
样例输出
4030

5:宠物小精灵之收服

总时间限制:
1000ms
内存限制:
65536kB
描述

宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事。


一天,小智和皮卡丘来到了小精灵狩猎场,里面有很多珍贵的野生宠物小精灵。小智也想收服其中的一些小精灵。然而,野生的小精灵并不那么容易被收服。对于每一个野生小精灵而言,小智可能需要使用很多个精灵球才能收服它,而在收服过程中,野生小精灵也会对皮卡丘造成一定的伤害(从而减少皮卡丘的体力)。当皮卡丘的体力小于等于0时,小智就必须结束狩猎(因为他需要给皮卡丘疗伤),而使得皮卡丘体力小于等于0的野生小精灵也不会被小智收服。当小智的精灵球用完时,狩猎也宣告结束。

我们假设小智遇到野生小精灵时有两个选择:收服它,或者离开它。如果小智选择了收服,那么一定会扔出能够收服该小精灵的精灵球,而皮卡丘也一定会受到相应的伤害;如果选择离开它,那么小智不会损失精灵球,皮卡丘也不会损失体力。

小智的目标有两个:主要目标是收服尽可能多的野生小精灵;如果可以收服的小精灵数量一样,小智希望皮卡丘受到的伤害越小(剩余体力越大),因为他们还要继续冒险。

现在已知小智的精灵球数量和皮卡丘的初始体力,已知每一个小精灵需要的用于收服的精灵球数目和它在被收服过程中会对皮卡丘造成的伤害数目。请问,小智该如何选择收服哪些小精灵以达到他的目标呢?

输入
输入数据的第一行包含三个整数:N(0 < N < 1000),M(0 < M < 500),K(0 < K < 100),分别代表小智的精灵球数量、皮卡丘初始的体力值、野生小精灵的数量。
之后的K行,每一行代表一个野生小精灵,包括两个整数:收服该小精灵需要的精灵球的数量,以及收服过程中对皮卡丘造成的伤害。
输出
输出为一行,包含两个整数:C,R,分别表示最多收服C个小精灵,以及收服C个小精灵时皮卡丘的剩余体力值最多为R。
样例输入
样例输入1:
10 100 5
7 10
2 40
2 50
1 20
4 20

样例输入2:
10 100 5
8 110
12 10
20 10
5 200
1 110
样例输出
样例输出1:
3 30

样例输出2:
0 100
提示
对于样例输入1:小智选择:(7,10) (2,40) (1,20) 这样小智一共收服了3个小精灵,皮卡丘受到了70点伤害,剩余100-70=30点体力。所以输出3 30
对于样例输入2:小智一个小精灵都没法收服,皮卡丘也不会收到任何伤害,所以输出0 100
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int l,m,n,minn;
int A[105][2];
int f[1005][505];
int main()
{
	scanf("%d %d %d",&m,&l,&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d %d",&A[i][0],&A[i][1]);
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=m;j>=A[i][0];j--)
		{
			for(int k=l;k>=A[i][1];k--)
			{
				f[j][k]=max(f[j][k],f[j-A[i][0]][k-A[i][1]]+1);
			}
		}
	}
	printf("%d ",f[m][l]);
	for(int i=0;i<=l;i++)
	{
		if(f[m][i]==f[m][l])
		{
			minn=i;
			break;
		}
	}
	printf("%d",l-minn);
}

6:单词序列

总时间限制:
1000ms
内存限制:
1024kB
描述

给出两个单词(开始单词和结束单词)以及一个词典。找出从开始单词转换到结束单词,所需要的最短转换序列。转换的规则如下:

1、每次只能改变一个字母

2、转换过程中出现的单词(除开始单词和结束单词)必须存在于词典中

例如:

开始单词为:hit

结束单词为:cog

词典为:[hot,dot,dog,lot,log,mot]

那么一种可能的最短变换是: hit -> hot -> dot -> dog -> cog,

所以返回的结果是序列的长度5;

注意:

1、如果不能找到这种变换,则输出0;

2、词典中所有单词长度一样;

3、所有的单词都由小写字母构成;

4、开始单词和结束单词可以不在词典中。

输入
共两行,第一行为开始单词和结束单词(两个单词不同),以空格分开。第二行为若干的单词(各不相同),以空格分隔开来,表示词典。单词长度不超过5,单词个数不超过30。
输出
输出转换序列的长度。
样例输入
hit cog
hot dot dog lot log
样例输出
5
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

struct Change
{
    string s;
    int step;
};
string s[50];
int len, cnt;
bool vis[50];
queue<Change> q;

void bfs()
{
    Change c;
    c.s = s[0], c.step = 0;
    q.push(c);
    vis[0] = 1;
    while(!q.empty())
    {
        Change now = q.front();
        q.pop();
        for(int i = 1; i <= cnt; i++)
        {
            int t = 0;
            for(int j = 0; j < len; j++)
                if(now.s[j] != s[i][j]) t++;
            if(t == 1 && !vis[i])
            {
                vis[i] = 1;
                Change nxt;
                nxt.s = s[i], nxt.step = now.step + 1;
                if(i == cnt) 
                {
                    printf("%d", nxt.step + 1);
                    return;
                }
                else q.push(nxt);
            }
        }
    }
    printf("0");
    return ;
}

int main()
{
    string sn;
    cin>>s[0]>>sn;
    len = sn.length();
    while(cin>>s[++cnt]);
    s[cnt] =sn;
    bfs();
    return 0;
}

7:Sudoku

总时间限制:
2000ms
内存限制:
65536kB
描述
Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task.
输入
The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty it is represented by 0.
输出
For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.
样例输入
1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107
样例输出
143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127
#include <stdio.h>
/* 构造完成标志 */
int sign;   //0代表false,1代表true 
/* 创建数独矩阵 */
int num[9][9];
/* 函数声明 */
void Input();
void Output();
int Check(int n, int key);//返回0代表false,1代表true 
int DFS(int n);
 
/* 主函数 */
main()
{	
    int test,i,j;
//	freopen("in.txt","r",stdin);
    scanf("%d",&test);
    while(test--)
    {
		sign=0;//设初始值为0 
	    Input();//输入 
	    DFS(0);  
	    Output();//输出   	
    }
}
 
/* 读入数独矩阵 */
void Input()
{
    int i,j;
    for (i = 0; i < 9; i++)
        for (j = 0; j < 9; j++)
        	scanf("%1d",&num[i][j]);//一个数一个数的读 
}
 
/* 输出数独矩阵 */
void Output()
{
    int i,j;
    for (i = 0; i < 9; i++)
    {
        for (j = 0; j < 9; j++)
        {
            printf("%d",num[i][j]);
        }
        printf("\n");
    }
}
 
/* 判断key填入n时是否满足条件 */
int Check(int n, int key)
{
    /* 判断n所在横列是否合法 */
    int i,j;
    int x,y;
    for (j = 0; j < 9; j++) 
    {
        /* i为n竖坐标 */
        i = n / 9;
		//如果有相同的数,返回0(不合法) 
        if (num[i][j] == key) return 0;
    }
 
    /* 判断n所在竖列是否合法 */
    for (i = 0; i < 9; i++)
    {
        /* j为n横坐标 */
        j = n % 9;
		//如果有相同的数,返回0(不合法) 
        if (num[i][j] == key) return 0;
    }
 
    /* x为n所在的小九宫格左顶点竖坐标 */
    x = n / 9 / 3 * 3;//如:38/9/3*3=3 
 
    /* y为n所在的小九宫格左顶点横坐标 */
    y = n % 9 / 3 * 3;//如:38%9/3*3=6 
 
    /* 判断n所在的小九宫格是否合法 */
    for (i = x; i < x + 3; i++)
    {
        for (j = y; j < y + 3; j++)
        {
            if (num[i][j] == key) return 0;
        }
    }
 
    /* 全部合法,返回正确 */
    return 1;
}
 
/* 深搜构造数独 */
int DFS(int n)
{
    /* 所有的都符合,退出递归 */
    int i;
    if (n > 80)
    {
        sign = 1;
        return 0;
    }
    /* 当前位不为空时跳过 */
    if (num[n/9][n%9] != 0)
    {
        DFS(n+1);
    }
    else
    {
        /* 否则对当前位进行枚举测试 */
        for (i = 1; i <= 9; i++)
        {
            /* 满足条件时填入数字 */
            if (Check(n, i) == 1)
            {
                num[n/9][n%9] = i;
                /* 继续搜索 */
                DFS(n+1);
                /* 返回时如果构造成功,则直接退出 */
                if (sign == 1) return 0;
                /* 如果构造不成功,还原当前位 */
                num[n/9][n%9] = 0;
            }
        }
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值