阿里云编程大赛初赛第一场(3/4)

A.树木规划

直接按顺序删即可。

class Solution {
public:
    /**
     * @param trees: the positions of trees.
     * @param d: the minimum beautiful interval.
     * @return: the minimum number of trees to remove to make trees beautiful.
     */
    int treePlanning(vector<int> &trees, int d) {
        // write your code here.
        int pre=trees[0];
        int ans=0;
        for (int i=1;i<trees.size();i++) {
            if (trees[i]-pre>=d) {
                pre=trees[i];
            }
            else {
                ans++;
            }
        }
        return ans;
    }
};
View Code

 

B.正三角形拼接

分类讨论,讨论方法在代码里。

class Solution {
public:
    /**
     * @param lengths: the lengths of sticks at the beginning.
     * @return: return the minimum number of cuts.
     */
   int makeEquilateralTriangle(vector<int> &lengths) {
        // write your code here.
        
        int ans=3;
        //分类讨论
        //第一类,已经有三根一样长的木棍,输出0
        //第二类,有两根长度一样的木棍,看看最长的木棍长度是否比这个长度大,如果是返回1
        //第三类,木棍长度互不相同,看是否有一根木棍的长度是当前木棍长度的两倍,如果是返回1
        //如果不是,看最长的一根木棍是否比这个两倍长,如果是返回2
        // 
        map<int,int> p;
        sort(lengths.begin(),lengths.end());
        for (int i=0;i<lengths.size();i++) p[lengths[i]]++;
        for (auto it=p.begin();it!=p.end();it++) {
            if (p[it->first*2]) {
                ans=min(ans,1);
            }
            if (it->second>=3) {
                ans=min(ans,0);
            }
            if (it->second>=2&&lengths.back()>it->first) {
                ans=min(ans,1);
            }
            if (lengths.back()>it->first*2) {
                ans=min(ans,2);
            }
        }
        return ans;
    }
};
View Code

 

D.对称前后缀

枚举所有子串,对于每个子串,二分最长对称前后缀,check这个过程可以用字符串哈希水过去,总体时间复杂度O(n*n*logn)。

class Solution {
public:
    /**
     * @param s: a string.
     * @return: return the values of all the intervals.
     */
  



long long suffixQuery(string &s) {
        // write your code here
    int n=s.length();
    long long f[3500]={0};
    long long p[3500]={0};
    long long f1[3500]={0};
    long long p1[3500]={0};
    f[0]=1;
    p[0]=1;
    f1[n+1]=1;
    p1[n+1]=1;
    for (int i=1;i<=n;i++) {
        f[i]=f[i-1]*13331+(s[i-1]+1);
        p[i]=p[i-1]*13331;
    } 
    for (int i=n;i>=1;i--) {
        f1[i]=f1[i+1]*13331+(s[i-1]+1);
        p1[i]=p1[i+1]*13331; 
    }
    long long ans=0;  
    for (int i=1;i<=n;i++) {
        for (int j=i;j<=n;j++) {
            if (i==j) {
                ans++;
                continue;
            }
            int l=1,r=j-i+1;
            int u=0;
            while (l<=r) {
                int mid=(l+r)>>1;//二分的最长对称前后缀 
                
                if (f[i+mid-1]-f[i-1]*p[mid]==f1[j-mid+1]-f1[j+1]*p[mid]) {
                    u=mid;
                    l=mid+1;
                }
                else {
                    r=mid-1;
                }
            } 
            if (!u) continue;
            //printf("%d<br>",u);
            ans+=u;
        }
    }
    return ans;
}
};
View Code

 

 

posted @ 2020-08-29 13:04  zlc0405  阅读(197)  评论(0编辑  收藏  举报