蓝桥杯矩阵求和_2020年9月15日蓝桥训练

题目列表:

  • 题目 1115: DNA:
    https://www.dotcpp.com/oj/problem1115.html

  • 题目 1282: 公交汽车:
    https://www.dotcpp.com/oj/problem1282.html

  • 题目 1508: [蓝桥杯][算法提高VIP]和最大子序列:
    https://www.dotcpp.com/oj/problem.php?id=1508

  • 题目 1907: [蓝桥杯][算法提高VIP]递推求值:
    https://www.dotcpp.com/oj/problem.php?id=1907

  • 题目 2108: 抢夺资源:
    https://www.dotcpp.com/oj/problem.php?id=2108

题目 1115: DNA

题目链接:https://www.dotcpp.com/oj/problem1115.html

题意:小强从小就喜欢生命科学,他总是好奇花草鸟兽从哪里来的。终于, 小强上中学了,接触到了神圣的名词--DNA。它有一个双螺旋的结构。这让一根筋的小强抓破头皮,“要是能画出来就好了” 小强喊道。现在就请你帮助他吧

思路:二维数组存储图形,按要求输出即可。

AC代码:

#include
#include
#include
#include

using namespace std;
const int N = 45;

char a[N][N];

int main(){
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n, m;
        scanf("%d%d", &n, &m);  

        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                a[i][j] = ' ';

        int y1 = 1, y2 = n;
        for(int i = 1; i <= n; i++)
        {
            a[i][y1] = 'X';
            a[i][y2] = 'X';
            y1++, y2--;
        }

        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++) printf("%c", a[i][j]);
            printf("\n");
        }

        m--;
        while(m--)
        {
            for(int i = 2; i <= n; i++)
            {
                for(int j = 1; j <= n; j++) printf("%c", a[i][j]);
                printf("\n");
            }
        }

        printf("\n"); 
    }

    return 0;
}

题目 1282: 公交汽车

题目链接:https://www.dotcpp.com/oj/problem1282.html

题意:一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里使来付费。例如下表就是一个费用的单子。  没有一辆车子行驶超过10公里,一个顾客打算行驶n公里(1< =n< =100),它可以通过无限次的换车来完成旅程。最后要求费用最少。

思路:可以通过无限次的换车来完成旅程,完全背包问题。本题求的是最小价值,所以初始值需要修改一下。

AC代码:

#include
#include
#include
#include

using namespace std;

int a[20];

int dp[110];

int main(){
    for(int i = 1; i <= 10; i++) scanf("%d", &a[i]);

    int n;
    scanf("%d", &n);

    memset(dp, 0x3f, sizeof dp);
    dp[0] = 0;

    for(int i = 1; i <= 10; i++)
    {
        for(int j = i; j <= n; j++)
        {
            dp[j] = min(dp[j], dp[j - i] + a[i]);
        }
    }

    printf("%d", dp[n]);

    return 0;
}

题目 1508: [蓝桥杯][算法提高VIP]和最大子序列

题目链接:https://www.dotcpp.com/oj/problem.php?id=1508

题意:对于一个给定的长度为N的整数序列A,它的“子序列”的定义是:A中非空的一段连续的元素(整数)。你要完成的任务是,在所有可能的子序列中,找到一个子序列,该子序列中所有元素的和是最大的(跟其他所有子序列相比)。程序要求你输出这个最大值。

分治法,AC代码:

#include
#include
#include
#include

using namespace std;

const int N = 100010;

int n;
int a[N];

int calc(int l, int r){
    if(l == r) return a[l];
    
    int mid = (l + r) >> 1;
    
    int left = calc(l, mid);
    int right = calc(mid + 1, r);
 
    int lmax = a[mid], lsum = 0;
    for(int i = mid; i >= l; i--)
    {
        lsum += a[i];
        lmax = max(lmax, lsum);
    }

    int rmax = a[mid + 1], rsum = 0;
    for(int i = mid + 1; i <= r; i++)
    {
        rsum += a[i];
        rmax = max(rmax, rsum);
    }

    return max(max(left, right), lmax + rmax);
}

int main(){
    scanf("%d", &n);
    for(int i = 0; i scanf("%d", &a[i]);

    printf("%d\n", calc(0, n - 1));

    return 0;
}

题目 1907: [蓝桥杯][算法提高VIP]递推求值

题目链接:https://www.dotcpp.com/oj/problem.php?id=1907

题意:

已知递推公式:

F(n, 1)=F(n-1, 2) + 2F(n-3, 1) + 5,

F(n, 2)=F(n-1, 1) + 3F(n-3, 1) + 2F(n-3, 2) + 3.

初始值为:F(1, 1)=2, F(1, 2)=3, F(2, 1)=1, F(2, 2)=4, F(3, 1)=6, F(3, 2)=5。输入n,输出F(n, 1)和F(n, 2),由于答案可能很大,你只需要输出答案除以99999999的余数。

思路:矩阵快速幂。

3c110adedf8cc6363151d06017d520aa.png
fd9a979f033013fffa85aeb89959ffea.png

AC代码:

#include
#include
#include
#include

using namespace std;
typedef long long ll;
const int mod = 99999999;

int f[7] = {6, 5, 1, 4, 2, 3, 1};

int a[7][7] = {{0, 1, 1, 0, 0, 0, 0},
               {1, 0, 0, 1, 0, 0, 0},
               {0, 0, 0, 0, 1, 0, 0},
               {0, 0, 0, 0, 0, 1, 0},
               {2, 3, 0, 0, 0, 0, 0},
               {0, 2, 0, 0, 0, 0, 0},
               {5, 3, 0, 0, 0, 0, 1}};

void mul(int f[7], int a[7][7]){
    int c[7];
    memset(c, 0, sizeof(c));
    for(int j = 0; j 7; j++)
        for(int k = 0; k 7; k++)
            c[j] = (c[j] + (ll)f[k] * a[k][j]) % mod;
    memcpy(f, c, sizeof(c));
}
 
void mulself(int a[7][7]){
    int c[7][7];
    memset(c, 0, sizeof(c));
    for(int i = 0; i 7; i++)
        for(int j = 0; j 7; j++)
            for(int k = 0; k 7; k++)
                c[i][j] = (c[i][j] + (ll)a[i][k] * a[k][j]) % mod;
    memcpy(a, c, sizeof(c));
}

int main(){
    ll n;
    scanf("%lld", &n);

    if(n == 1) printf("2\n3\n");
    else if(n == 2) printf("1\n4\n");
    else if(n == 3) printf("6\n5\n");
    else
    {
        n -= 3;
        while(n)
        {
            if(n & 1) mul(f, a);
            mulself(a);
            n >>= 1;
        }
        printf("%d\n%d\n", f[0], f[1]);
    }

    return 0;
}

题目 2108: 抢夺资源

题目链接:https://www.dotcpp.com/oj/problem.php?id=2108

题意:杰洛特在面对敌将时,总是需要获得更多的资源才能战胜敌人,很可惜,敌人也是这么想的。因此他们共同来到一个城市买物资(两位都有无限的钱),本城市中一共有n个物资,他们俩轮流进行购买(由杰洛特先买),每一次购买可以买 1……m 个物资,最先刚好购买光商品的人可以获胜。

思路:巴什游戏。

关于巴什游戏的详细讲解:巴什游戏与SG函数

AC代码:

#include
#include
#include

using namespace std;

int main(){
    int n, m;
    while(~scanf("%d%d", &n, &m))
    {
        if(n % (m + 1) == 0) puts("Wildhunte");
        else puts("Gerlot");
    }

    return 0;
}

9be0e4a1a7a5fbf8dcdd85489a0c893c.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值