蓝桥杯——砍竹子问题(C++)


问题描述

评测用例规模与约定


输入格式

输出格式

       


样例输入

6

2 1 4 2 6 7

样例输出

5


观察题目,不难想到的第一种方法,即利用贪心策略,每次砍断竹子最大的且连续的队列,由于队列中会出现很多重复长度的竹子造成算法冗余,故我还加入了去重的操作,奈何时间还是超限...  但对于小数据样本是可以的

#include<iostream>
#include<math.h>
using namespace std;

int cut(long long bamboo[], int n);
int Maxbamboo(long long bamboo[], int n);
int compression(long long bamboo[], int n, int &m);

int main()
{
    long long bamboo[200000];
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> bamboo[i];
    cout << cut(bamboo, n) << endl;
    return 0;
}

int cut(long long bamboo[], int n)
{
    int count = 0;
    int m, len;
    //每次砍最高的竹子
    while(m = Maxbamboo(bamboo, n),bamboo[m]!=1)
    {
        len = compression(bamboo, n, m);
        long long key = bamboo[m];
        long long data = sqrt(key / 2 + 1);
        for (int i = m; i < len && bamboo[i] == key; i++)
            bamboo[i] = data;
        count++;
        n = len;
    }
    return count;
}

int Maxbamboo(long long bamboo[], int n)
{
    int max = 0;
    for (int i = 0; i < n; i++)
        if(bamboo[i] > bamboo[max])
            max = i;
    return max;
}

int compression(long long bamboo[], int n, int &m)
{
    int pre = bamboo[0];
    int len = 1;
    for (int i = 1; i < n ; i++)
    {
        if(bamboo[i]!=pre)
        {
            if(i == m)
                m = len;
            bamboo[len++] = bamboo[i];
            pre = bamboo[i];
        }
    }
    return len;
}

由于时间超限,故我选择搜寻他法,找到了另一种灵活算法,它的基本思想就是利用代价,每次让每个相邻不同的竹子进行代价计算,遇到相同梯次时即可停止,因为后续它们会一起砍断。此处@b站up主,3258 砍竹子_哔哩哔哩_bilibili

#include<iostream>
#include<math.h>
using namespace std;

int cut(long long bamboo[], int n);

int main()
{
    long long bamboo[200000];
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> bamboo[i];
    cout << cut(bamboo, n) << endl;
    return 0;

}

int cut(long long bamboo[], int n)
{
    long long echelon[10000];
    int len = 0,count = 0;
    while(bamboo[0] > 1)
    {
        echelon[len++] = bamboo[0];count++;
        bamboo[0] = sqrt(bamboo[0] / 2 + 1);
    }
    for (int i = 1; i < n; i++)
    {
        long long v = bamboo[i];
        while(v > 1)
        {
            int flag = 0;
            for (int j = 0; j < len; j++)
                if(echelon[j]==v)
                { flag = 1;break; }
            if(flag) break;
            count++;
            v = sqrt(v / 2 + 1);
        }
        len = 0;
        while(bamboo[i]>1)
        {
            echelon[len++] = bamboo[i];
            bamboo[i] = sqrt(bamboo[i] / 2 + 1);
        }
    }
    return count;
}

猜你喜欢

转载自blog.csdn.net/qq_63761366/article/details/128680913