zoukankan      html  css  js  c++  java
  • 早晨训练赛第一场 B题 哈希

    早晨训练赛第一场 B题

    B - Trees in a Row
    Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

    Description

    The Queen of England has n trees growing in a row in her garden. At that, the i-th (1 ≤ i ≤ n) tree from the left has height ai meters. Today the Queen decided to update the scenery of her garden. She wants the trees' heights to meet the condition: for all i(1 ≤ i < n), ai + 1 - ai = k, where k is the number the Queen chose.

    Unfortunately, the royal gardener is not a machine and he cannot fulfill the desire of the Queen instantly! In one minute, the gardener can either decrease the height of a tree to any positive integer height or increase the height of a tree to any positive integer height. How should the royal gardener act to fulfill a whim of Her Majesty in the minimum number of minutes?

    Input

    The first line contains two space-separated integers: nk (1 ≤ n, k ≤ 1000). The second line contains n space-separated integersa1, a2, ..., an (1 ≤ ai ≤ 1000) — the heights of the trees in the row.

    Output

    In the first line print a single integer p — the minimum number of minutes the gardener needs. In the next p lines print the description of his actions.

    If the gardener needs to increase the height of the j-th (1 ≤ j ≤ n) tree from the left by x(x ≥ 1) meters, then print in the corresponding line "+ j x". If the gardener needs to decrease the height of the j-th (1 ≤ j ≤ n) tree from the left by x(x ≥ 1) meters, print on the corresponding line "- j x".

    If there are multiple ways to make a row of trees beautiful in the minimum number of actions, you are allowed to print any of them.

    Sample Input

    Input
    4 1
    1 2 1 5
    Output
    2
    + 3 2
    - 4 1
    Input
    4 1
    1 2 3 4
    Output
    0

    题意:给定n棵树,每棵树的高度为a[i],每次可将一棵树砍掉或增加任意高度,给定一个整数k,求砍或增的最少次数使得树的高度满足a[i+1]-a[i]=k(即斜率为k)
    思路:由于数据是1000,所以直接暴力,枚举任意序列中的数对a[i]和a[j]组成的直线,选择a[k]中在该直线上最多的直线,然后修改树的高度。复杂度o(n^3).
    然而如果数据改为10^6呢,当然有更神奇的o(n)解法.
        将每个数减去k*(j-1),即将所求的斜直线变为横直线,这样求经过点最多的横直线只需扫一遍数组,用map记录下每个横直线经过的点数,再扫一遍找出最优的横直线,再扫一遍即可算出答案了。复杂度o(n)!!!
    然后这里有一点比较坑的是树的高度不能出现负数.
    下面是o(n)的代码:
    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn=1000100;
    const int INF=(1<<29);
    typedef long long ll;
    
    int n,k;
    int a[maxn];
    map<int,int> mp;
    
    int main()
    {
        while(cin>>n>>k){
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            mp.clear();
            for(int i=1;i<=n;i++) a[i]-=(i-1)*k;
            for(int i=1;i<=n;i++) mp[a[i]]++;
            int Max=-INF,x=1;
            for(int i=1;i<=n;i++) if(mp[a[i]]>Max&&a[i]>0) Max=mp[x=a[i]];
            int cnt=0;
            for(int i=1;i<=n;i++) if(a[i]!=x) cnt++;
            cout<<cnt<<endl;
            for(int i=1;i<=n;i++){
                if(a[i]!=x){
                    if(x-a[i]>0) printf("+ %d %d
    ",i,x-a[i]);
                    else printf("- %d %d
    ",i,a[i]-x);
                }
            }
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    【C】C99与C89区别以及转换方法
    【bug】warning #13200: No emms instruction before return from function
    【linux/makefile】-D_REENTRANT编译选项的作用
    【arm】arm交叉编译工具链使用说明
    【Linux】linux中的strip命令
    【Linux】nm命令中符号类型详解
    【link】illegal text-relocation in IOS platform
    【link】IOS平台下汇编函数符号链接问题
    【ffmpeg】ffserver搭建流媒体服务
    【economic】程序员外包平台
  • 原文地址:https://www.cnblogs.com/--560/p/4528773.html
Copyright © 2011-2022 走看看