Article directory
1. Pure prime numbers
You can refer to
the number theory template - prime number sieve, divisor, Euler function
Method 1: Trial division
Time complexity: O(nsqrt(n))
timeout
i<n/i
Method 2: The most common sieve method
Sieve all multiples of numbers in turn
Time complexity O(nlogn)
timeout
#include <iostream>
#include <cstring>
using namespace std;
const int N=20210605,M=N+10;
bool st[M];
bool check(int num){
// for(int i=num;i>0;i/=10){
// if(st[i%10])return false;
// }
while(num){
if(st[num%10])return false;
num/=10;
}
return true;
}
int main()
{
int ans=0;
st[0]=true;
st[1]=true;
for(int i=2;i<=N;i++){
if(!st[i]&&check(i))ans++;
for(int j=i*2;j<=N;j+=i){
st[j]=true;
}
}
printf("%d",ans);
return 0;
}
Method 3: Eh-sieve method
Sieve all the multiples of prime numbers in turn
Time complexity O(nloglogn)
#include <iostream>
#include <cstring>
using namespace std;
const int N=20210605,M=N+10;
bool st[M];
bool check(int num){
// for(int i=num;i>0;i/=10){
// if(st[i%10])return false;
// }
while(num){
if(st[num%10])return false;
num/=10;
}
return true;
}
int main()
{
int ans=0;
st[0]=true;
st[1]=true;
for(int i=2;i<=N;i++){
if(!st[i]){
if(check(i))ans++;
for(int j=i*2;j<=N;j+=i){
st[j]=true;
}
}
}
printf("%d",ans);
return 0;
}
Method 4: Linear sieve method
Composite numbers will only be sieved by the smallest prime factor, and each number will only be sieved once, so it is a linear
time complexity O(n)
optimal
#include <iostream>
#include <cstring>
using namespace std;
const int N=20210605,M=N+10;
bool st[M];
int prime[M];
int cnt;
bool check(int num){
// for(int i=num;i>0;i/=10){
// if(st[i%10])return false;
// }
while(num){
if(st[num%10])return false;
num/=10;
}
return true;
}
int main()
{
int ans=0;
st[0]=true;
st[1]=true;
for(int i=2;i<=N;i++){
if(!st[i]){
if(check(i))ans++;
prime[cnt++]=i;
}
for(int j=0;prime[j]<N/i;j++){
st[prime[j]*i]=true;
if(i%prime[j]==0)break;
}
}
printf("%d",ans);
return 0;
}
2. Minimum weight
Learn from the 2021 Blue Bridge Cup: Minimum Weight == Balanced Ternary / Greedy
Balanced Ternary
Method 1: Greedy (find the law)
#include <iostream>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
int t=1;
int ans=0;
while(n>0){
n-=t;
t*=3;
ans++;
}
printf("%d",ans);
return 0;
}
Method 2: Balanced ternary
Convert standard ternary to balanced ternary { − 1 , 0 , 1 } , the bit is -1 on the left, 1 on the right, and 0 on the right.
Therefore, this problem can also be done in the same way:
that is, find a balanced ternary number for the input n, and the number of digits is the answer
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int>list;
while(n){
list.push_back(n%3);
n/=3;
}
for(int i=0;i<list.size();i++){
if(list[i]==2){
list[i]=-1;
if(i+1<list.size())list[i+1]+=1;
else list.push_back(1);
}else if(list[i]==3){
list[i]=0;
if(i+1<list.size())list[i+1]=1;
else list.push_back(1);
}
}
printf("%d",list.size());
return 0;
}
3. Irrigation
Thank you @ 不 row not change classmates for pointing out that map[x][y] should be marked after passing through
#include <iostream>
#include <vector>
using namespace std;
const int N=110;
typedef pair<int,int>PII;
int dx[4]={
-1,0,1,0},dy[4]={
0,1,0,-1};
bool map[N][N];//判断是否已被灌溉
int main()
{
int n,m;
int t,r,c;
vector<PII>pipe;
int k;
scanf("%d%d",&n,&m);
scanf("%d",&t);
for(int i=0;i<t;i++){
scanf("%d%d",&r,&c);
pipe.push_back({
r,c});
map[r][c]=true;//有出水管的位置可以被认为已经灌溉好
}
scanf("%d",&k);
while(k--){
int len=pipe.size();
for(int i=0;i<len;i++){
auto pos=pipe[i];
for(int j=0;j<4;j++){
int x=pos.first+dx[j];
int y=pos.second+dy[j];
if(!map[x][y]&&x>=1&&x<=n&&y>=1&&y<=m){
pipe.push_back({
x,y});
map[x][y]=true;
}
}
}
}
printf("%d",pipe.size());
return 0;
}