牛客编程巅峰赛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;
}
};
查看7道真题和解析