蓝桥杯赛前冲刺30天打卡题解(Day4)

1.奇数倍数

 

思路: 从小到大枚举所有2019的整数倍数,判断枚举数的每一位是否为奇数,返回第一个满足条件的数。

#include <iostream>
using namespace std;
int main()
{
  int a=2019,b=0,c=0;
  for(int i=1;;i++)
  {
    b=0;c=0;
    int bz=1;
    c=a*i;
    while(c!=0)
    {
      b=c%10;
      c=c/10;
      if(b%2==0) bz=0;
    }
    if(bz==1) {cout<<i*a;break;}
  }
  return 0;
}

 2.第几个幸运数字

思路: 

方法有很多,能够使用最小堆解题,时间复杂度是O ( n l g n ) O(n lgn)O(nlgn),其中n代表所求数字时第n 个幸运数字。不过这里我推荐使用三指针+动态规划的做法,具体方法如下:

定义数组数组d p dpdp从小到大存储所有的幸运数字,我们知道幸运数字一定是只有3 、 5 、 7 为因子的数字,因此任意一个幸运数字一定能够将其乘以3 、 5 、 7 ,得到新的幸运数字,也就是说幸运数字一定能够由比它小的幸运数字乘以3 或 5 或 7推算出来。
 

那么既然这样对于第i ii位的幸运数字究竟由哪一位推算出来呢?此时可以定义i d x 3   i d x 5   i d x 7 idx3 ~idx5 ~idx7 分别存储供应位,表示该位的值提供新的幸运数字,提供的幸运数字分别是d p [ i d x 3 ] ∗ 3 , d p [ i d x 5 ] ∗ 5 , d p [ i d x 7 ] ∗ 7 。开始时值都为0,d p [ 0 ] =1,此时提供幸运数字分别是:

1∗3=3

1∗5=5

1∗7=7

获取这三位供应幸运数字的最小值,就是当前位上的幸运数字,如果当前位上的幸运数字大于等于某一个供应位提供的幸运数字,那么表示该位供应的幸运数字已经出现在数组中,该供应位向后移动一位。

循环直到出现最小值也就是当前位幸运数字与所求相等时,返回当前位数i 。时间复杂度:O ( N ) 

#include<bits/stdc++.h>
using namespace std; 
int main()
{ 
    long long n = 59084709587505;
    int ans = 0;
    for(long long i = 1; i <= n; i *= 3) 
    {
        for(long long j = 1; i*j <= n; j *= 5)
        {
            for(long long k = 1; k*i*j <= n; k *= 7)
            {
                ans++;
            }
        }
    }
    cout << ans - 1;
    return 0;
}

3.四平方和 

 

方法1:暴力

#include <iostream>
#include <cmath>
using namespace std;
int main(){
    int n;
    scanf("%d",&n);
    for(int a=0;a*a<=n;a++){
        for(int b=a;a*a+b*b<=n;b++){
            for(int c=b;a*a+b*b+c*c<=n;c++){
                int t=n-a*a-b*b-c*c;
                int d=sqrt(t);
                if(d*d==t){
                    printf("%d %d %d %d",a,b,c,d);
                    return 0;
                }
            }
        }
    }
    return 0;
}

 PS:时间复杂不符合要求。故换第二种方法

 方法2:二分
时间复杂度:O(n2 logn)

 

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=5*1e6+10;
bool g[N];
struct Sum{
    int s,c,d;
    bool operator <(const Sum& t)const{
        if(s!=t.s)return s<t.s;
        if(c!=t.c)return c<t.c;
        return d<t.d;
    }
}sum[N];
int main(){
    int n,len=0;
    scanf("%d",&n);
    for(int c=0;c*c<=n;c++){
        for(int d=c;c*c+d*d<=n;d++){
            sum[len++]={c*c+d*d,c,d};
        }
    }
    sort(sum,sum+len);
    for(int a=0;a*a<=n;a++){
        for(int b=0;b*b+a*a<=n;b++){
            int t=n-a*a-b*b;
            int l=0,r=len-1;
            while(l<r){
                int mid=(l+r)/2;
                if(sum[mid].s>=t)r=mid;
                else l=mid+1;
            }
            if(sum[l].s==t){
                printf("%d %d %d %d",a,b,sum[l].c,sum[l].d);
                return 0;
            }
        }
    }
    return 0;
}

4.迷宫 

 

 

#include <iostream>
#include <vector>
using namespace std;
const int N=33,M=53;
char g[N][M];
typedef pair<int,int>PII;
vector<char>ans;
PII que[N*M];
int hh=0,tt=-1;
PII pre[N][M];
void bfs(){
  int dx[4]={1,0,0,-1},dy[4]={0,-1,1,0};
  que[++tt]={0,0};

  while(hh<=tt){
    auto t=que[hh++];
    for(int i=0;i<4;i++){
      int x=dx[i]+t.first;
      int y=dy[i]+t.second;

      if(g[x][y]=='0'&&x>=0&&x<30&&y>=0&&y<50){
     
        que[++tt]={x,y};
        pre[x][y]=t;
        g[x][y]='1';
      }
    }
  }

  int x=29,y=49;
  int prex,prey;
  while(x||y){

    auto t=pre[x][y];
    prex=t.first;
    prey=t.second;

    if(x-prex==1){
      ans.push_back('D');
    }else if(x-prex==-1){
      ans.push_back('U');
    }else if(y-prey==1){
      ans.push_back('R');
    }else if(y-prey==-1){
      ans.push_back('L');
    }
    x=prex;
    y=prey;
  }

int main()
{

  for(int i=0;i<30;i++){
    for(int j=0;j<50;j++){
      scanf("%c",&g[i][j]);
    }
    getchar();
  }

    bfs();
   
      for(int i=ans.size()-1;i>=0;i--){
        printf("%c",ans[i]);
      }
  return 0;
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小灰QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值