CCF 201909-1 小明种苹果 CCF 201909-2 小明种苹果(续)

CCF 201909-1 小明种苹果

CCF 201909-1 小明种苹果 CCF 201909-2 小明种苹果(续)_第1张图片

思路:

小明种了N棵树,进行M轮疏果操作,求M轮过后所有树剩余多少个苹果、哪棵树疏果个数最多,并求出树的编号。
枚举每棵树,求每棵树剩余苹果树,摘的数量,剩余苹果树取和,摘的数量取绝对值。

代码实现:

#include 
#include 
#include 

using namespace std;

int main()
{
    int n, m;//棵树、疏果轮数
    scanf_s("%d%d", &n, &m);

    int T = 0, K, P = -1;//最后剩余苹果数、疏果个数最多的树编号、该苹果数的疏果个数
    for (int i = 1; i <= n; i++)
    {
        int tot, sum = 0, x;
        scanf_s("%d", &tot);//输入第i棵树上的苹果总数
        for (int j = 0; j < m; j++)
        {
            scanf_s("%d", &x);//读入第j轮疏果时从第i棵树上摘的苹果数(可以为负数)
            sum += abs(x);//疏果数累加
        }
        T += tot - sum;//疏果结束第i棵树剩余的苹果总数
        if (sum > P) K = i, P = sum;//储存疏果最多的树编号及数目
    }
    cout << T << ' ' << K << ' ' << P << endl;
    return 0;
}
//海大海之子考研老哥QQ:1151039635
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

CCF 201909-2 小明种苹果(续)

思路:

(1)苹果总数(输入的第一个数)-摘掉数(小于等于0的数)-自然脱落数(D)=剩余数(T)。
剩余数T=最后一个大于0的时刻减去之后所有摘掉的苹果数量。
(2)自然脱落数D=苹果总数-摘掉数(小于等于0的数)-剩余数T
(3)E:遍历所有树是否连续三课树的脱落数D都大于0
此题又是题目意思不明确,需要多次分析从中找出数学公式就比较好做了。

代码实现:

#include 
#include 
#include 
#include 

using namespace std;

const int N = 1010;

int n;//苹果数量
vector<int> q[N];//每颗苹果数的操作存放在vector中
bool st[N];//存储当前苹果数是够自然脱落
//计算剩余数T=最后一个大于0的时刻减去之后所有摘掉的苹果数量。
int get(vector<int>& a, int k)
{
    int res = a[k];
    for (int i = k + 1; i < a.size(); i++)
        if (a[i] <= 0)
            res += a[i];
    return res;
}

int main()
{
    scanf_s("%d", &n);
    for (int i = 0; i < n; i++)
    {
        int k;
        scanf_s("%d", &k);//当前苹果树操作的次数
        while (k--)
        {
            int x;
            scanf_s("%d", &x);//读入随后的k个数:含总数等
            q[i].push_back(x);
        }
    }

    int T = 0, D = 0, E = 0;//剩余数、自然脱落数、连续三棵树自然脱落的组数
    for (int i = 0; i < n; i++)
    {
        int a, b;//每棵苹果数的总数、摘掉的数
        //从后往前找第一个大于0的位置,即剩余数T=最后一个大于0的时刻减去之后所有摘掉的苹果数量。
        for (int j = q[i].size() - 1; j >= 0; j--)
            if (q[i][j] > 0)
            {
                a = get(q[i], j);//j表示从哪里开始计算
                break;
            }
        b = get(q[i], 0);//从第一个数开始计算摘掉的数量
        T += a;
        if (b > a) st[i] = true, D++;//若摘掉数大于苹果的总数则说明发生过自然掉落
    }
    //枚举若连续3棵树都自然脱落
    for (int i = 0; i < n; i++)
        if (st[i] && st[(i + 1) % n] && st[(i + 2) % n])
            E++;
    printf("%d %d %d\n", T, D, E);
    return 0;
}

CCF 201909-1 小明种苹果 CCF 201909-2 小明种苹果(续)_第2张图片

你可能感兴趣的:(CCF代码每日一练,算法)