3

蓝桥31天|每天3道题Day1

 2 years ago
source link: https://blog.csdn.net/weixin_45627369/article/details/123352106
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

1.纯质数

在这里插入图片描述
可参考
数论模板-素数筛、约数、欧拉函数

法一:试除法
时间复杂度:O(nsqrt(n))
超时
i<n/i

法二:最普通的筛法
依次筛去所有数的倍数

时间复杂度 O(nlogn)
超时

#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;
}

newCodeMoreWhite.png

法三:诶式筛法
依次筛去所有质数的倍数

时间复杂度 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;
}
newCodeMoreWhite.png

法四:线性筛法
合数只会被最小质因子筛掉,每个数只会被筛一次,所以是线性的

时间复杂度 O(n)
最优

#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;
}

newCodeMoreWhite.png

2.最少砝码

在这里插入图片描述
借鉴2021 蓝桥杯:最少砝码 == 平衡三进制/贪心
平衡三进制
法一:贪心(找规律)
在这里插入图片描述

#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;
}
newCodeMoreWhite.png

法二:平衡三进制
在这里插入图片描述
将标准三进制转换为平衡三进制{ − 1 , 0 , 1 } ,该位为-1放左边,为1放右边,为0不放。
因此本题也可以这样做:
即,对输入的 n 求平衡三进制数,该数的位数即为答案

#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;
}
newCodeMoreWhite.png

在这里插入图片描述

#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});
        }
      }
    }
  }
  printf("%d",pipe.size());
  
  return 0;
}
newCodeMoreWhite.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK