超级码力在线编程大赛初赛一

那天是考试,随便打了一下,但是被编译器整吐了,输入的测试样例不能调,而且还不是题目给的样例。
数组定义在class里面没初始化wa吐了,但是定义到外面也得初始化就玄学了。。。
说到底还是菜,菜哭我了。

正三角形拼接

思路:
最多肯定只需要两次操作。
但如果可以找出x与x*2,那么只需要一次操作。
如果存在出现两次的数且这个数不是最大数,那么只需要一次操作。
如果存在出现三次的数,那么不需要操作。

class Solution {
public:
    /**
     * @param lengths: the lengths of sticks at the beginning.
     * @return: return the minimum number of cuts.
     */
    map<int,int>mp;
    int makeEquilateralTriangle(vector<int> &lengths) {
        // write your code here.
        sort(lengths.begin(),lengths.end());
        int n = lengths.size();
        int ans = 2;
        for(int i = 0;i < n;i++) {
            mp[lengths[i]]++;
        }
        for(int i = 0;i < n;i++) {
            if(mp[lengths[i]] == 3) {
                ans = min(ans,0);
            }
            if(mp[lengths[i]] == 2 && lengths[i] != lengths[n - 1]) {
                ans = min(ans,1);
            }
            if(mp[lengths[i] * 2]) {
                ans = min(ans,1);
            }
        }
        return ans;
    }
};

树木规划

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 n = trees.size();
        int ans = 0;
        int pre = trees[0];
        for(int i = 1;i < n;i++) {
            if(trees[i] - pre < d) {
                ans++;
            } else {
                pre = trees[i];
            }
        }
        return ans;
    }
};

对称前后缀
定义 d p [ i ] [ j ] dp[i][j] 为s[i,j]的对称前后缀的长度,子状态就是 d p [ i + 1 ] [ j 1 ] dp[i+1][j-1]
但要是 d p [ i ] [ j ] = ( l e n + 1 ) / 2 dp[i][j]=(len+1)/2 l e n len 为串的长度,那么说明这个串整个就是回文串,整个串都可以算贡献。

typedef unsigned long long ull;
#pragma GCC optimize(2)
long long dp[3005][3005];
class Solution {
public:
    /**
     * @param s: a string.
     * @return: return the values of all the intervals.
     */

    long long suffixQuery(string &s) {
        int n = s.size();
        // write your code here
        memset(dp,0,sizeof(dp));
        for(int i = 1;i <= n;i++) dp[i][i] = 1;
        for(int i = 2;i <= n;i++) {
            for(int j = 1;j + i - 1 <= n;j++) {
                int k = j + i - 1;
                if(s[j-1] == s[k-1]) {
                    dp[j][k] = max(dp[j][k],dp[j+1][k-1] + 1);
                }
            }
        }
        long long ans = 0;
        for(int i = 1;i <= n;i++) {
            for(int j = i;j <= n;j++) {
                int len = j - i + 1;
                if(len % 2 == 1) {
                    if(dp[i][j] == len / 2 + 1) ans += len;
                    else ans += dp[i][j];
                } else if(len % 2 == 0) {
                    if(dp[i][j] == len / 2) ans += len;
                    else ans += dp[i][j];
                }
            }
        }
        return ans;
    }
};

大楼间穿梭

思路: 裸的单调队列+dp。

class Solution {
public:
    /**
     * @param heights: the heights of buildings.
     * @param k: the vision.
     * @param x: the energy to spend of the first action.
     * @param y: the energy to spend of the second action.
     * @return: the minimal energy to spend.
     */
    long long dp[100005];
    int right[100005];
    int q[100005];
    long long shuttleInBuildings(vector<int> &heights, int k, int x, int y) {
        // write your code here.
        memset(right,0,sizeof(right));
        int n = heights.size();
        int l = 1,r = 0;
        for(int i = 1;i <= n;i++) {
            while(l <= r && i - q[l] > k) {
                l++;
            }
            while(l <= r && heights[i - 1] >= heights[q[r] - 1]) {
                right[q[r]] = i;
                r--;
            }
            q[++r] = i;
        }
        for(int i = 1;i <= n;i++) {
            printf("%d ",right[i]);
        }
        memset(dp,0x3f,sizeof(dp));
        dp[1] = 0;
        for(int i = 1;i <= n;i++) {
            dp[i + 1] = min(dp[i + 1],dp[i] + y);
            dp[i + 2] = min(dp[i + 2],dp[i] + y);
            if(right[i] != 0) {
                dp[right[i]] = min(dp[right[i]],dp[i] + x);
            }
        }
        return dp[n];
    }
};

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/108331160
今日推荐