2020牛客寒假算法基础集训营1 rin和快速迭代
题目链接:https://ac.nowcoder.com/acm/contest/3002/E
题意:就是给一个数,然后求它的因数个数,然后再求它的因数个数的因数个数,以此类推,一直找到第多少次它的因数个数的因数个数是2.
解法:是和队友搞的!队友看过的人数跟我说可能可以暴力!我就,花了半个小时证明嗯确实可以暴力 其实没必要啊喂 然后搞了个暴力结果wa了但是后来改对了就是直接递归,每个递归里面遍历前√n个数,如果能整除就直接答案+=2,最后单独判断一下√n能不能被整出,能的话再+=1。
代码:
#include<cstdio>
#include<cmath>
#define sqs 0.00000000001
using namespace std;
int cnt = 0;
long long temp = 1;
while(temp < sqrt(now))
{
if(now % temp == 0)
{
cnt += 2;
}
temp ++;
}
if(temp - sqrt(now) <= sqs) cnt ++;
return cnt;
}
int main(void)
{
long long n;
scanf("%lld",&n);
int cnt = 0;
long long temp = get(n);
// printf("temp = %lld\n",temp);
while(temp != 2)
{
temp = get(temp);
// printf("temp = %lld\n",temp);
cnt ++;
}
printf("%d\n",cnt + 1);
return 0;
}
2020牛客寒假算法基础集训营1 eli和字符串
题目链接:https://ac.nowcoder.com/acm/contest/3002/G
题意:问一个字符串里面含有k个相同字母的最短串的长度。
解法:首先它求最短,那肯定就是axxxxa这种,就是开头和结尾肯定都是满足要求的那个字母,因此我直接将字符串里面出现的所有字母的位置都记下来,如果所有的字母出现的次数都比要求的k少那就直接输出0,否则就两两相减,如果满足条件就直接更新ans = min (ans , pos[i+1] - pos[i] + 1) 这样。
代码:
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int MAX_SIZE = 200005;
vector<int>b[26];
char a[MAX_SIZE];
int cnt[26];
int main(void)
{
int n,k;
scanf("%d%d",&n,&k);
scanf("%s",a);
for(int i = 0; i < n; i ++ )
{
cnt[a[i]-'a']++;
b[a[i]-'a'].push_back(i);
}
int flag = 1;
for(int i = 0; i < 26; i ++ )
{
if(cnt[i] >= k)
{
flag = 0;
break;
}
}
if(flag)
{
printf("-1\n");
return 0;
}
int ans = INF;
for(int i = 0 ; i < 26 ; i ++ )
{
if(cnt[i] < k) continue;
else{
int temp = 0;
for(int j = 0 ; j < cnt[i] - k + 1 ; j ++ )
{
// printf("%d %d\n",b[i][j],b[i][j+k-1]);
temp = b[i][j + k - 1] - b[i][j] + 1;
ans = min(temp,ans);
// printf("%d\n",ans);
}
}
}
if(ans == INF) printf("-1\n");
else printf("%d\n",ans);
return 0;
}
2020牛客寒假算法基础集训营2 做计数
题目链接:https://ac.nowcoder.com/acm/contest/3003/E
题意:给了一个n,范围在1~4e7,然后要求i * j <= n,并且满足√i + √j = √k ,( i , j , k )组成正整数三元组,i,j的不同顺序可以算不同的三元组,问一共多少个不同的三元组。
解法:根据 √i + √j = √k 可以两边同时平方得到 i + j + 2√(ij) = k,首先可以肯定i,j都是整数,而且题目要求的k是个正整数,所以可以肯定√(ij)也是个正整数,那么只要满足 i * j <= n && √(i * j) - (int)√(i * j) <= sqs 就行了。~~这里其实做题的时候卡了半天因为我一直弄的判断条件是i,j都要是平方数,但是这个条件其实并不必要,因为只要满足ij是个平方数,那么i,j分别是平方数的可能性就已经被包含进去了,就很傻【哔——】~~
代码:
#include<cstdio>
#include<cmath>
#include<vector>
#define sqs 0.0000000001
using namespace std;
int main(void){
int n;
scanf("%d",&n);
int node = sqrt(n);
int cnt = 0;
int ans = 0;
for(int i = 1; i * i <= n; i ++ )
{
cnt = 0;
int now = i*i;
int temp = 1;
while(temp < i)
{
if(now % temp == 0)
{
cnt ++;
}
temp ++;
}
ans += (cnt * 2 + 1);
}
printf("%d\n",ans);
return 0;
}
2020牛客寒假算法基础集训营2 判正误
题目链接:https://ac.nowcoder.com/acm/contest/3003/G
题意:判断 a^d + b ^e + c ^f == g ,abcdefg都是1e9的。
解法:是个裸的快速幂,但是模数比较迷人。看官方题解也是给了好几个模数让多试几次,但其实还是有点点迷惑一定是我太菜了呜呜呜呜。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MOD 1000000009
using namespace std;
const int MAX_SIZE = 105;
char num[MAX_SIZE];
long long binaryPow(long long a, long long b, long long m) {
long long ans = 1;
a = a % m;
b = b % m;
while(b > 0) {
if(b & 1) {
ans = ans * a % m;
}
a = a * a % m;
b >>= 1;
}
return ans;
}
2020牛客寒假算法基础集训营3 牛牛的数组越位
题目链接:https://ac.nowcoder.com/acm/contest/3004/C
题意:就是给一个数组但是是不规范的写法,然后如果给的数组的输入方法会直接访问越界就输出Runtime error,如果输入的不规范,但是能成功赋值就把赋值后的数组输出并且输出Undefined Behaviour,如果正常输入就将成功赋值后的数组输出并输出Accept。
解法:根据它给的那个输入的位置就是xm + y这个,可以先得到输入的范围是在0 ~ nm范围内,所以上来先判断这步如果不在这个范围内那就直接re,否则再给它整成一个一维数组再按行输出就行。
代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX_SIZE = 1000;
int num[3000005];
int n,m,p;
int main(void)
{
int T;
scanf("%d",&T);
while(T--)
{
memset(num,0,sizeof(num));
int flag = 0;
scanf("%d%d%d",&n,&m,&p);
// printf("%d\n",0%5);
int hugest = n*m;
while(p--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
long long temp;
temp = x*m + y;
if(temp < hugest && temp >= 0)//正常输入
{
if(x >= 0 && x <= n && y >= 0 && y <= m)
{
num[(int)temp] = z;
//printf("temp = %lld num[temp] = %d\n",temp,num[(int)temp]);
}
else{
if(flag != 1) flag = 2;
// if(temp == 0)
// {
// num[0][0] = z;
// continue;
// }
// if(temp % m == 0 && (temp / m) % 2 == 0)
// {
// y = m - 1;
// }else if(temp % m == 0 && (temp / m) % 2 != 0) y = 0;
// else y = temp % m ;
// if(temp / m == 0)
// {
// x = 0;
// }else x = temp / m;
num[(int)temp] = z;
// printf("temp = %lld num[temp] = %d\n",temp,num[(int)temp]);
}
// printf("x = %d y = %d z = %d\n",x,y,z);
}else
{
flag = 1;
}
}
if(flag == 1)
{
printf("Runtime error\n");
}else if(flag == 2)
{
for(int i = 0; i < n * m; i ++ )
{
if((i + 1) % m == 0) printf("%d\n",num[i]);
else printf("%d ",num[i]);
}
printf("Undefined Behaviour\n");
}else{
for(int i = 0; i < n * m; i ++ )
{
if((i + 1) % m == 0) printf("%d\n",num[i]);
else printf("%d ",num[i]);
}
printf("Accepted\n");
}
}
return 0;
}
2020牛客寒假算法基础集训营3 牛牛的k合因子数
题目链接:https://ac.nowcoder.com/acm/contest/3004/H
题意:就是1~n的每个数的因子中一共多少个非素数因子【算他自己但不算1】。
解法:先用埃氏筛预处理一下,得到给定范围内的所有素数,然后就直接和训练营1的那个E题快速迭代一样硬来,就是每步多加一个判断是不是素数,如果不是素数就ans++。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int MAX_SIZE = 100005;
int num[MAX_SIZE];
bool isprime[MAX_SIZE];
int n,m;
void sieve()
{
for(int i = 0; i <= n; i ++ )
{
isprime[i] = true;
}
isprime[0] = isprime[1] = false;
for(int i = 2; i <= n; i ++ )
{
if(isprime[i])
{
for(int j = 2 * i; j <= n; j += i)
{
isprime[j] = false;
}
}
}
// for(int i = 1; i <= n ;i ++ )
// {
// printf("%3d",i);
// }
// printf("\n");
// for(int i = 1; i <= n; i ++ )
// {
// printf("%3d",isprime[i]);
// }
// printf("\n");
}
int ans[MAX_SIZE];
int find(int now)
{
int ans = 0;
int temp = 1;
for(int i = 1; i <= sqrt(now); i ++ )
{
if(now % i == 0)
{
// printf("temp = %d now/temp = %d\n",temp,now/temp);
if(now == i * i)
{
if(isprime[i] == false && i != 1)
ans++;
}else{
if(isprime[i] == false && i != 1)
{
ans ++;
}
if(isprime[now/i] == false && now/i != 1)
{
ans ++;
}
}
}
}
// printf("%d %d\n",now,ans);
return ans;
}
int cnt[MAX_SIZE];
int main(void)
{
scanf("%d%d",&n,&m);
sieve();
// find(8);
for(int i = 1; i <= n; i ++ )
{
ans[i] = find(i);
}
for(int i = 1; i <= n; i ++ )
{
cnt[ans[i]]++;
}
for(int i = 1; i <= m; i ++ )
{
int ask;
scanf("%d",&ask);
printf("%d\n",cnt[ask]);
}
return 0;
}