Codeforces Round #236 (Div. 2)__Trees in a Row

题目链接

  • 反思:
    上来方向就错了,仍然是对公式进行化简并找到了规律。诚然,这个方法是效率高,可是花费在代码和调试上的时间已经宣告了这个题目的失败
    题目的数据不大,是可以O(n^2)枚举的
  • 以后结题的方向:
    充分利用枚举!!!上来先考虑枚举,在考虑算法
O(n ^ 2)
const int MAXN = 11000;

int ipt[MAXN];

int main()
{
//    freopen("in.txt", "r", stdin);
    int n, goal;
    while (~RII(n, goal))
    {
        FE(i, 1, n)
            RI(ipt[i]);
        int Max = -INF, index;
        FE(i, 1, n)
        {
            if (ipt[i] + goal * (1 - i) < 1)
                continue;
            int t = 0;
            FE(j, 1, n)
            {
                if (ipt[j] - ipt[i] == goal * (j - i))
                    t++;
            }
            if (t > Max)
            {
                Max = t;
                index = i;
            }
        }
        cout << n - Max << endl;
        int value = ipt[index] - goal * index;

        FE(i, 1, n)
        {
            if (ipt[i] - goal * i > value)
                printf("- %d %d\n", i, ipt[i] - goal * i - value);
            else if (ipt[i] - goal * i < value)
                printf("+ %d %d\n", i, value - ipt[i] + goal *i);
        }
    }
    return 0;
}

接下来完成一下最开始的思路:O(n)

对于位置i和j,如果他们不用进行变化,那么需要满足的条件:ipt[j] - ipt[i] = goal * (j - i),我们化简一下可以得到:ipt[i] - goal * i =ipt[j] - goal * j,到这里规律就很明显了,可以计算出每个点的ipt[i] - goal * i,计算出这个值相同的数量的最大值。这个地方就有一个坑,题目要求每个点都是正整数而且是递增,那么在ipt[1]是有约束的,必须大于零,判断很简单关键是要想到这个约束。

const int MAXN = 110000;

int ipt[MAXN];
map<int, int> mp;

int main()
{
//    freopen("in.txt", "r", stdin);
    int t, n, goal;
    while (~RII(n, goal))
    {
        mp.clear();
        FE(i, 1, n)
            RI(ipt[i]);
        FE(i, 1, n)
        {
            if (ipt[i] - goal * i + goal >= 1)
                mp[ipt[i] - goal * i]++;
        }
        int Max = -INF, value;
        FC(it, mp)
        {
            if ((t = it->second) > Max)
            {
                Max = t;
                value = it->first;
            }
        }
        cout << n - Max << endl;

        FE(i, 1, n)
        {
            if (ipt[i] - goal * i > value)
                printf("- %d %d\n", i, ipt[i] - goal * i - value);
            else if (ipt[i] - goal * i < value)
                printf("+ %d %d\n", i, value - ipt[i] + goal *i);
        }
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值