西南交通大学算法分析与设计第三次作业

题目1:古卡萨人为了建造一个高塔,先采集了大量不同类型的石块。每种类型的石块的高度为hi数量为ci。他们在修建高塔之前,先通过占卜确定每种类型的石块能够摆放的最大高度,然后再将他们一块一块垒起来,最终完成了高塔的建造。

    请你根据现有石块的情况计算出他们最高能够建造出的高塔的高度。

输入要求:输入第1行为整数n,表示石块的类型。其后有n行,每一行包含三个整数hi (1 <= hi <= 100) ,ai(1 <= ai <= 40000),ci(1 <= ci <= 10),分别表示该类型的石块的高度,该类型石块能够摆放在塔上的最大高度以及该类型石块的数量。

输出要求:输出1行,包含一个整数,也就是利用这些石块能够建造的高塔的最大高度。

样例输入:

3

7 40 3

5 23 8

2 52 6

样例输出:

48


#include<iostream>
#include <vector>
#include <algorithm>
using namespace std;

int maxHeight = 0, n;
const int N = 1010;

typedef struct stone {
    int height;  
    int limit;  
    int count;  
} stone;

stone stones[N];

void dfs(int u, int curHeight) {
    if (u == n) {
        maxHeight = max(curHeight, maxHeight);
        return;
    }
    for (int i = 0; i <= stones[u].count; i++) {
        if (curHeight + i * stones[u].height <= stones[u].limit)
            dfs(u + 1, curHeight + i * stones[u].height);
    }
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> stones[i].height >> stones[i].limit >> stones[i].count;
    }
    sort(stones, stones + n, [](stone a, stone b) -> bool {
        return a.limit < b.limit;
    });
    dfs(0, 0);
    cout << maxHeight;
    return 0;
}

题目2围棋由方形网格棋盘和黑白棋子构成。现在棋盘的某方形区域内摆满棋子,下图为该棋盘4*4的区域内摆放棋子的情况。如果用b和w表示该方形网格中棋子的颜色,b为黑色,w为白色。这样该图形可用下面来的矩阵来表示:

bwbw

wwww

bbwb

bwwb

现玩一个游戏,游戏规则是:如果将其中的某一个棋子由黑色变成白色(称为一次变换),则周围四个方向上的棋子将会改变颜色,也就是如果原来棋子的颜色是白色则变成黑色,是黑色则会变成白色。比如上面的棋盘中,将第三行第一个棋子由黑色变成白色,则对应的棋盘会变成下面的颜色:

bwbw

bwww

wwwb

wwwb   

    上述这样的变换称为一次变换。请编写程序,希望通过最少次数的变换将棋盘中的棋子全部变成白色或者黑色。

输入要求:输入第一行为整数n,表示棋盘中放摆放棋子的行数和列数,其后的n行,每行有n个字符,由b和w组成,分别表示棋子的初始颜色。

输出要求:输出1个整数,占1行,表示最少的变换次数。

样例输入:

bwwb
bbwb
bwwb
bwww

样例输出:

4 
#include <iostream>
#include <algorithm>
using namespace std;
char chess[4][4],now[]={'w','b'};
int ans=1<<27;

char revise(char c)
{
    if(c==now[0]) return now[1];
    else return now[0];
}

bool in(int x,int y)
{
    if(x>=0 && x<4 && y>=0 && y<4)
        return true;
    return false;
}

bool isOk(char board[4][4])
{
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            if(board[i][j]!=board[0][0]) return false;
    return true;
}

void op(int x,int y)
{
    chess[x][y]=revise(chess[x][y]);
    if(in(x+1,y))  chess[x+1][y]=revise(chess[x+1][y]);
    if(in(x-1,y))  chess[x-1][y]=revise(chess[x-1][y]);
    if(in(x,y-1))  chess[x][y-1]=revise(chess[x][y-1]);
    if(in(x,y+1))  chess[x][y+1]=revise(chess[x][y+1]);
}

void dfs(int x,int y,int k)
{
    if(isOk(chess))
    {
        ans=min(ans,k);
        return;
    }

    if(!in(x,y)) return;

    int newy=(y+1)%4;
    int newx=x+(y+1)/4;

    dfs(newx,newy,k);
    op(x,y);
    dfs(newx,newy,k+1);
    op(x,y);
}

int main()
{
    for(auto & ches : chess)
        for(char & che : ches)
            cin>>che;

    dfs(0,0,0);
    if(ans==1<<27) cout<<"Impossible";
    else cout<<ans;
    return 0;
}

题目3:迷宫游戏(软件班完成该作业)

算法输入:

1n*n迷宫数组(最外层为墙壁),其中元素的含义为:2—墙壁;0—通路。

2、迷宫入口和出口坐标。

3、测试用例如下图,入口为(11),出口为(77)。

算法输出:

1、路径条数;2、从入口到出口的最短路径长度;3、打印每条路径的示意图。4、绘制出迷宫问题的解空间树(只画两层)和第一条完整路径(如下图)的搜索空间树(可以手绘在纸上,拍照)。从入口(11)开始到出口(77),每个格子按照右、下、左、上的顺序搜索下一个格子。在解空间和搜索空间树的节点中写上格子的坐标

 

#include "iostream"
#include "vector"

using namespace std;

int map[100][100];
bool tag[100][100];
int n, m;
int endx, endy;
int short_count = 10000;

bool check(int i, int j) {
    if (i < 0 || i >= m || j < 0 || j >= n) {
        return false;
    }
    if (map[i][j] == 2) {
        return false;
    }
    if (tag[i][j]) {
        return false;
    }
    return true;
}

bool dfs(int i, int j, int cnt) {
    tag[i][j] = true;
    if (i == endx && j == endy) {
        short_count = short_count <= cnt ? short_count : cnt;
        return true;
    }
    bool result1 = false, result2 = false, result3 = false, result4 = false;
    if (check(i, j + 1)) {
        result1 = dfs(i, j + 1, cnt + 1);
    }
    if (check(i + 1, j)) {
        result2 = dfs(i + 1, j, cnt + 1);
    }
    if (check(i, j - 1)) {
        result3 = dfs(i, j - 1, cnt + 1);
    }
    if (check(i - 1, j)) {
        result4 = dfs(i - 1, j, cnt + 1);
    }
    if (result1 || result2 || result3 || result4) {
        return true;
    } else {
        tag[i][j] = false;
        return false;
    }
}

int main() {
    int startx, starty;
    cin >> n >> m >> startx >> starty >> endx >> endy;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            cin >> map[i][j];
        }
    }
    dfs(startx, starty, 0);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (tag[i][j]) {
                cout << " ! " ;
            } else {
                cout << " " << map[i][j] << " " ;
            }
        }
        cout << endl;
    }
    cout << "Short Count: " << (short_count == 10000 ? -1 : short_count) << endl;
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jellyfish Knight

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值