質問D:
小さな思考と法則
まず
、25/5は正確に割り切れることがわかります。これはブレークスルーポイントと見なされます。5未満のすべての数について、25 / iの数は繰り返されません。 i番目の数はセット内の数でもあります.i(大きいものから小さいものへ); 5より大きい場合、重複があります。つまり、25 / iの値が密になり、これらが見つかります。値は1になるまで継続します。
#include <bits/stdc++.h>
using namespace std;
int n,x;
int t;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> t;
while(t--)
{
cin >> n >> x;
if(x <= int(sqrt(n)))
{
cout << x << '\n';
}
else
{
int cnt = int(sqrt(n));
cnt += (n / (cnt + 1) - n / x) + 1;
//这一步不能写成 cnt += (cnt - n / x);
// n=24 k=5
cout << cnt << '\n';
}
}
return 0;
}
質問F
両端キューは当面問題を解決しません
質問I
素数が2、3、5、7などの素数でない場合は、何桁かを知る必要があります。
#include <bits/stdc++.h>
#define maxn 4000086
using namespace std;
const int p = 1e9 + 7;
int n;
int prm[maxn], cnt;
bool tag[maxn];
int f[maxn], g[maxn];
// f[i] 存的是 i 最小的质因子
int main(){
scanf("%d", &n);
for(int i = 2;i <= n;i++)
{
if(!tag[i]) prm[++cnt] = i, f[i] = i;
for(int j = 1;j <= cnt && prm[j] * i <= n;j++)
{
tag[prm[j] * i] = true, f[prm[j] * i] = prm[j];
if(i % prm[j] == 0) break;
}
}
for(int i = 2;i <= n;i++){
// 用g[i]表示i是几位数
int x = i;
g[i] = 1;
while(x){
x /= 10;
g[i] *= 10;
}
}
int ans = 0;
for(int i = 2;i <= n;i++)
{
int sum = 0, x = i;
while(x ^ 1)
{
// f[i] 始终为最小质因数 模拟一下就能懂这个过程
sum = (1ll * sum * g[f[x]] + f[x]) % p;
x /= f[x];
}
ans = (ans + sum) % p;
}
printf("%d", ans);
}
J質問
思考質問
#include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
cin >> n;
int a[50];
a[0]= 1;
a[1]= 2;
// 小于40 就用斐波那契数列
for (int i = 1; i <= min(40, n); i++)
{
cout << a[i] <<' ';
a[i+1] = a[i]+a[i-1];
}
// 大于40就用斐波那契数列 + 一堆1往后托
for (int i = 41; i <= n; i++)
cout << 1 <<' ';
return 0;
}