1. 程式人生 > 實用技巧 >阿里雲程式設計大賽初賽第一場(3/4)

阿里雲程式設計大賽初賽第一場(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