牛客编程巅峰赛S1第2场 - 青铜&白银
A
这个题目挺简单的,难点在于题目没说清(?),输入和输出描述里字符串是带双引号的,但是实际上却不需要,然后写了一堆羸弱代码我的做法很简单,因为所以我就直接暴力了,素数也因为挺少,就直接手写了一个素数数组,直接循环判断一下那个是否为素数
class Solution { public: /** * * @param x string字符串 字符串从前到后分别是从上到下排列的n张扑克牌 * @return string字符串 */ string Orderofpoker(string x) { // write code here int sushu[5]={1,2,3,5,7}; string ans = ""; int len = x.length() / 2; int i = 0, j = x.length() - 2; for (; len; --len) { int flag=0; for(int i=0;i<5;++i){ if(sushu[i]==len) flag=1; } if (flag) ans += x.substr(i, 2), i += 2; else ans += x.substr(j, 2), j -= 2; } return ans; } };
B
题目的意思就是一个数组然后在其中找一个最大的子数组,数组中的元素呈先向上增加,然后先下递减,所以叫金字塔数组循环遍历一次数组,遇到不断维护最大的就行(代码很容易看懂),然后就是这个金字塔一定要先递增然后递减(其实不递减也可以,昨天直播的时候听到了好像是说没卡到这个点)
class Solution { public: /** * * @param n int整型 * @param num int整型vector * @return int整型 */ int getMaxLength(int n, vector<int>& num) { // write code here int cnt1 = 0,cnt2 = 0,ans=0; int flag = 0; for(int i = 1 ; i < n ; ++i){ if(num[i] > num[i-1]){ if(flag) cnt1 = 0; cnt1++; cnt2 = 0; flag = 0; } else if(num[i] < num[i-1]){ cnt2++; flag = 1; if(cnt1!=0) ans = max(cnt1+cnt2,ans); } else{ cnt1 = 0; cnt2 = 0; } } //cout<<ans<<endl; //system("pause"); return ans+1; } };
C
这个题我并没有做出来,打完之和和别人讨论也是在讨论错的(也不能算错的只是异常的麻烦),容斥,直接求的话要考虑好多种情况,考虑放两个,三个四个在边上,这里要考虑的太多了,看了直播之后才知道,原来是我太蠢了,正难则反,那么我们就反过来考虑,先求出所有的情况,然后减掉不需要的不就好了吗,(果然我是***),代码也好理解,就是四条边那些边不放,算出全部的情况减一下就好了class Solution { public: /** * * @param n int整型 * @param m int整型 * @param k int整型 * @return int整型 */ long long f[2000][2000]; long long mod=1e9+7; void calc(int n){ for(int i=0;i<=n;++i) f[i][0]=f[i][i]=1; for(int i=1;i<=n;++i) for(int j=1;j<i;++j) f[i][j]=(f[i-1][j-1]+f[i-1][j])%mod; } int solve(int n, int m, int k) { // write code here calc(n*m); long long ans=0; for(int i=0;i<=1;++i) for(int j=0;j<=1;++j) for(int x=0;x<=1;++x) for(int y=0;y<=1;++y){ int c=i+j; int h=x+y; int d=c+h; if(d%2==1) ans=(ans-f[(n-c)*(m-h)][k]+mod)%mod; else ans=(ans+f[(n-c)*(m-h)][k]+mod)%mod; } return ans; } };