牛客周赛31 (地址:https://ac.nowcoder.com/acm/contest/74362。)
第一题 A:小红小紫替换
题目链接:https://ac.nowcoder.com/acm/contest/74362/A
题意:
当且仅当字符串等于“kou”时,将字符串替换为“yukari”,其余字符串直接输出(简单签到题)
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
string a;
cin >>a;
if (a=="kou")return cout <<"yukari\n",0;//判断字符串是等于“kou”,是的话直接结束代码
//这里的return cout <<"yukari\n",0;是将return 0;和cout <<"yukari\n";两行代码的合并写法。
cout <<a<<"\n";
return 0;
}
第二题 B:小红的因子数
题目链接:https://ac.nowcoder.com/acm/contest/74362/B
题意:
题目给你一个实数x(1<=x<=10^13),求x有多少个不同的素因子.
如果按纯暴力解的想法是从2开始遍历一遍,如果该因子能把该数整除,并且是素数,那种类就加1,很显然这种方法的复杂度肯定超了,那我们要怎么想呢?
理解题意,我们要找是的是素数因子,素数是不能被除1和自身以外整除的数,所以当x从2开始遍历的时候,倘若i能把x整除,那就一直除到i不能把x整除为止,这样就保证了接下来的可以把x整除的数必然是素数。
例子:x=12,当i=2时,把x除到2不能整除时,x=3。
代码:
for (i=2;i<=x;i++)
{
if (x%i==0)//判断i是否能把x整除
{
s++;//记录因子个数
while(x%i==0)x/=i;//将x除到i不能整除为止。
}
}
那问题又来了,这样遍历依然是从2到x,复杂度不是还会超吗?别急,上面的代码是算法的优化,接下来是AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long x,i;//开long long不然会爆
long long s=0;//同理,必须要开o(一︿一+)o
cin >>x;
//从i*i限制范围,也是i要开loong long的原因,但i*i显然是判断不了x自身是素数的情况的
for (i=2;i*i<=x;i++)
{
if (x%i==0)
{
s++;
while(x%i==0)x/=i;
}
}
if (x>1)s++;//所以加上特判如果x大于1,就说明x没被除尽,剩下的数为素数,s+1
cout <<s<<"\n";
return 0;
}
第三题 C:小红的字符串中值
题目链接:https://ac.nowcoder.com/acm/contest/74362/C
题意:
给你一个字符串长度n,查找的单个字符x,以及字符串a,求字符x是字符串a中多少个子串的中值。
定义:中值即字符串中间的那个字符,如“kou”的中值是‘o’。
听起来有点复杂和绕,又是找字符又是子串的,别急,让我们一步步来。
首先,我们肯定是要从字符串a中找到字符x的,怎么找?遍历嘛,那遍历的时候,当找到了字符a时,它所在的位置也就找到了,而题目说x必须是字符串的中值,那是不是只要比较当前字符x的左右两边存在的字符个数哪个小,就可以决定x可以组成几个子串了?这就很清晰了嘛。(≧▽≦)ノ
什么还看不太懂?
以题目例子1举例:
n=4,x=b,a=abcb。
当循环到第一个b时:
当循环到第二个b时:
由此可得比较的代码是:
min(i,n-i-1);//可以组成的子串个数
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
char x;
string a;
long long s=0;//int相加,开long long。
cin >>n>>x>>a;
for (int i=0;i<n;i++)
{
if (a[i]==x)s+=min(i,n-i-1)+1;//加1是因为只要找到,他自身就是一个子串
}
cout <<s<<"\n";
return 0;
}
ok,以上就是整篇文章,See you next time!