牛客编程巅峰赛S1第2场 - 青铜&白银

A.牛牛扔牌

链接:https://ac.nowcoder.com/acm/contest/6219/A
来源:牛客网

题目描述

牛牛现在有n张扑克牌,每张扑克牌都有点数和花色两部分组成。点数为‘1’-‘9’的正整数,花色为'C','D','H','S''其中的一个,分别表示梅花、方块、红桃、黑桃。现在牛牛想按一定的顺序把这n张牌扔掉。扔牌顺序的规则如下1.:

1.如果现在还剩素数张牌,则将牌顶的牌扔掉

2.如果现在还剩非素数张牌,则将牌底的牌扔掉

牛牛想知道他的扔牌顺序是什么,请返回扔牌顺序的字符串

思路:

直接模拟就行了。

class Solution {
public:
    /**
     * 
     * @param x string字符串 字符串从前到后分别是从上到下排列的n张扑克牌
     * @return string字符串
     */
    int is_prime(int num)
    {
        if (num == 1)
            return false;
        for (int i = 2; i < num; i++)
        {
            if (num % i == 0)
                return false;
        }
        return true;
    }
    string Orderofpoker(string x) 
    {
        cin >> x;
        deque<string>dq;
        for (int i = 0; i < x.size(); i += 2)
        {
            if (i == x.size() - 1)
                continue;
            string z = x.substr(i, 2);
            dq.push_back(z);
        }
        string ans;
        while (!dq.empty())
        {
            int num = dq.size();
            if (!is_prime(num))
            {
                ans += dq.back();
                dq.pop_back();
            }
            else
            {
                ans += dq.front();
                dq.pop_front();
            }
        }
        return ans;
    }
};

B.疯狂过山车

链接:https://ac.nowcoder.com/acm/contest/6219/B
来源:牛客网
 

题目描述

今天牛牛去游乐园玩过山车项目,他觉得过山车在上坡下坡的过程是非常刺激的,回到家之后就受到启发,想到了一个问题。如果把整个过山车的轨道当作是一个长度为n的数组num,那么在过山车上坡时数组中的值是呈现递增趋势的,到了最高点以后,数组中的值呈现递减的趋势,牛牛把符合这样先增后减规律的数组定义为金字塔数组,请你帮牛牛在整个num数组中找出长度最长的金字塔数组,如果金字塔数组不存在,请输出0。

思路:

维护两个数组,一个L表示从前到当前位置的最长连续递增长度,R表示从后到当前最长连续递增长度。

class Solution {
public:
    /**
     * 
     * @param n int整型 
     * @param num int整型vector 
     * @return int整型
     */
    int getMaxLength(int n, vector<int>& num) 
    {
    	vector<int>L, R;
        R.resize(n + 10);
        L.resize(n + 10);
        int ans = 0;
        vector<int>v = num;
        int last = -1, cnt = 0;
        for (int i = 1; i <= n; i++)
        {
            int z = v[i - 1];
            v.push_back(z);
            if (z > last)
                cnt++;
            else
                cnt = 1;
            L[i] = cnt;
            last = z;
        }
        last = v[n - 1];
        R[n] = 1;
        cnt = 1;
        for (int i = n - 2; i >= 0; i--)
        {
            if (v[i] > last)
                cnt++;
            else
                cnt = 1;
            R[i + 1] = cnt;
            last = v[i];
        }
        ans = 0;
        for (int i = 1; i <= n; i++)
        {
            ans = max(L[i] + R[i] - 1, ans);
        }
        return ans;
    }
};

C.牛牛的棋盘

链接:https://ac.nowcoder.com/acm/contest/6219/C
来源:牛客网
 

题目描述

牛牛最近在家里看到一个棋盘,有n*m个格子,在棋盘旁边还放着k颗棋子,牛牛想把这k颗棋子全部放在n*m的棋盘上,但是有一个限制条件:棋盘的第一行、第一列、最后一行和最后一列都必须有棋子。牛牛想知道这样的棋子放法到底有多少种,答案需要对1e9+7取模。

思路:

四个角比较特殊,枚举四个角的情况,再枚举第一行第一列,最后一行最后一列的个数,剩下的直接组合数计算即可。

typedef long long ll;
class Solution {
public:
	/**
	*
	* @param n int整型
	* @param m int整型
	* @param k int整型
	* @return int整型
	*/
        static const int mod = 1e9 + 7;
        ll C[1010][1010];
        void init()
        {
            C[0][0] = C[1][0] = C[1][1] = 1;
            for (int i = 2; i <= 1000; i++)
            {
                C[i][0] = 1;
                for (int j = 1; j <= i; j++)
                    C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
            }
        }
	int solve(int n, int m, int k)
	{
        init();
        int u, v, w, x;
        ll ans = 0;
        for (int sta = 0; sta < (1 << 4); sta++)
        {
            u = v = w = x = 0; //看下第一行最后一行一列,第一列最后一列有没有
            int zs = bool(sta & (1 << 0));//左上
            int ys = bool(sta & (1 << 1));//右上
            int zx = bool(sta & (1 << 2));//左下
            int yx = bool(sta & (1 << 3));//右下
            if (zs)
                u++, w++;
            if (ys)
                u++, x++;
            if (zx)
                v++, w++;
            if (yx)
                v++, x++;
            for (int a = 0; a <= m - 2; a++) //第一行
            {
                for (int b = 0; b <= m - 2; b++) //最后一行
                {
                    for (int c = 0; c <= n - 2; c++)//第一列
                    {
                        for (int d = 0; d <= n - 2; d++)//最后一列
                        {
                            if (!a && !u)
                                continue;
                            if (!b && !v)
                                continue;
                            if (!c && !w)
                                continue;
                            if (!d && !x)
                                continue;
                            int last = k - (zs + ys + zx + yx + a + b + c + d);//剩余
                            if (last < 0)
                                continue;
	                        ans = (ans + C[(n - 2) * (m - 2)][last] * C[m - 2][a] % mod * C[m - 2][b] % mod * C[n - 2][c] % mod * C[n - 2][d] % mod) % mod;
                        }
                    }
                }
            }
        }
        return ans;
	}
};

猜你喜欢

转载自blog.csdn.net/weixin_43731933/article/details/107293309