2018年蓝桥杯软件B组省赛试题(部分)


第几天(简单计算)

在这里插入图片描述


明码(STL专题之bitset)

在这里插入图片描述

这一个题的意思就是把题目中所给的数字变成二进制的码来表示,然后每两个数字的码是在一排的.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<bitset>
#include<algorithm> 
using namespace std;

typedef long long LL;
const int Max_n=100005;
    
int main(){
/*  int n,m;
    while(~scanf("%d%d",&n,&m)){
        bitset<8>x;
        x=n;
        for(int i=7;i>=0;i--){
            if(x[i]) printf("1");
            else printf(" "); 
        }
        x=m;
        for(int i=7;i>=0;i--){
            if(x[i]) printf("1");
            else printf(" "); 
        }
        printf("\n");
    }*/
    //上面的显示的是:九的九次方等于多少?
    printf("%.0lf",pow(9,9)); //387420489
    return 0;
}

乘积尾零(思维,简单计算)

在这里插入图片描述

找0的个数实际上就是找2和5的数量.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

typedef long long LL;
const int Max_n=30;
int a[Max_n];

int main() {
    for(int i=1;i<=100;i++)
        scanf("%d",&a[i]);
    int num1=0;
    int num2=0;
    for(int i=1;i<=100;i++){
        int x=a[i];
        while(x%2==0&&x){
            x/=2;
            num1++;
        }
        while(x%5==0&&x){
            x/=5;
            num2++;
        }
    }
    printf("%d\n",num1>num2?num2:num1);//31
    return 0;
}

快速排序(找第k小的数)

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMjE3Mzc2,size_16,color_FFFFFF,t_70

代码的大概意思就是先随机生成一个数,把比这个小的都放在它的左边,比它大的数都放在右边,这个数如果是第k小的就返回,如果小于k就再向右半部分,此时就不是第k小的了,否则就向左边去找第k小的数.`


递增三元组(STL专题之二分的应用)

在这里插入图片描述

这题不好想到的就是遍历b,如果遍历a复杂度最多降到O(nlogn).

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm> 
using namespace std;

typedef long long LL;
const int Max_n=100005;
int a[Max_n],b[Max_n],c[Max_n];
    
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
        scanf("%d",&b[i]);
    for(int i=1;i<=n;i++)
        scanf("%d",&c[i]);
    sort(a+1,a+1+n);
    sort(c+1,c+1+n);
    LL ans=0;
    for(int i=1;i<=n;i++){
        int index1=lower_bound(a+1,a+1+n,b[i])-a;
        int index2=upper_bound(c+1,c+1+n,b[i])-c;
        ans+=1LL*(index1-1)*(n-index2+1);
    }
    printf("%lld\n",ans);
    return 0;
}

螺旋折线(思维,数学)

在这里插入图片描述

在这里插入图片描述

把每一圈都补成一个正方形,然后讨论点落在四个方向上的情况.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<bitset>
#include<algorithm> 
using namespace std;

typedef long long LL;
const int Max_n=100005;
    
int f(int x,int y,int n){
    if(x==-n){
        if(y==-n) 
            return 8*n;//n*2*4;
        return y+n;//1+(y+n-1);
    }
    if(y==n){
        return 3*n+x;//1+2*n-1+x+n;
    }
    if(x==n){
        return 5*n-y;//1+2*n-1+2*n+n-y;
    }
    if(y==-n){
        return 7*n-x;//1+2*n-1+2*n+2*n+n-x;
    }
}

int main(){
    int x,y;
    scanf("%d%d",&x,&y);
    int n=max(abs(x),abs(y));
    LL ans=1LL*n*(n-1)*4+f(x,y,n);
    printf("%lld\n",ans);
    return 0;
}

日志统计(尺取法)

在这里插入图片描述

  • 首先我们先对每个id在哪个时间收到的赞全部保存在一个vector中,相当于一个邻接表.
  • 保存完了以后我们先遍历每一个id
  • 判断某个id在[T,T+D)内是否是热帖
    • 先判断此id对应的赞一共有多少个,也就是id对应的长度,如果小于k直接返回false,
      如果大于k可能有满足条件的区间,我们就对这个id对应的ts进行排序。
    • 对于满足情况的时候,我们可以先从第一个时间开始,如果赞没有k个右指针右移,cnt++
      如果够了k个,我们就需要判断这些时间间隔是否在D内,如果在就返回true.如果不
      在D内,说明时间间隔需要缩短,此时左指针左移,cnt--.
  • 如果是热帖就放入数组中,否则继续遍历id,直到结束为止.

我们需要明确的是:v[i]里面的一个数就代表一个赞.

#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring> 
using namespace std;

typedef long long LL;
const int Max_n=1005;
int ans[Max_n],n,d,k;;//保存符合条件的id 
vector<int>v[Max_n];

bool judge(int id){
    int len=v[id].size();
    if(len<k) return false;
    sort(v[id].begin(),v[id].end());//按照时间从小到大排序
    int l=0,r=0;
    int cnt=0;//表示目前得到的赞.
    while(l<=r&&r<len){//某个区间,并且右端点不能超过边界.
        cnt++;//如果上一步cnt<k,那么我们r++之后cnt是要加1的.
        //(此时一个时间就代表一个赞)如果我们上一步是没有找到
        //合适的区间,l++,cnt--因为此时我们的赞已经固定在k了,
        //所以我们需要cnt++(增加时间间隔) 
        if(cnt>=k){//此时赞是够的,只需要在看时间段是否符合就行. 
            if(v[id][r]-v[id][l]<d) return true;
            else{//此时间间隔不满足说明左端点需要右移(缩短间隔)
                l++;
                cnt--; 
            } 
        }
        r++;//赞不够我们增加赞,如果是因为时间间隔我们需要右移左端点
        //(因为此时我们已经将赞固定的k个了,再往后遍历,删除一个就要增加一个) 
    } 
    return false;//最后没有找到合适的时间间隔
}

int main(){
    scanf("%d%d%d",&n,&d,&k);
    while(n--){
        int id,ts;
        scanf("%d%d",&ts,&id);
        v[id].push_back(ts);
    }
    int num=0; 
    for(int i=1;i<=Max_n;i++){
        if(judge(i)){
            ans[++num]=i;
        } 
    }
    for(int i=1;i<=num;i++)
        printf("%d\n",ans[i]);
    return 0;
} 

全球变暖(dfs&连通块)

在这里插入图片描述
此题有一个坑点,就是让求有多少岛屿被完全淹没,而不是最终还剩下多少岛屿.

#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<set> 
using namespace std;

typedef long long LL;
const int Max_n=1005;
char a[Max_n][Max_n];
int vis[Max_n][Max_n],n,vis1[Max_n][Max_n];
int net[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
set<char>s;

bool judge_border(int x,int y){
    if(x<1||x>n||y<1||y>n)
        return false;
    return true;
} 

void dfs(int x,int y,int color){//标记连通块 
    a[x][y]=color;
    for(int k=0;k<4;k++){
        int tx=x+net[k][0];
        int ty=y+net[k][1];
        if(judge_border(tx,ty)&&!vis[tx][ty]&&a[tx][ty]=='#'){
            vis[tx][ty]=1;
            dfs(tx,ty,color);
        }
    }
    return ;
}


int main(){
    char cnt='0';
    scanf("%d",&n); 
    getchar();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf(" %c",&a[i][j]);
    for(int i=1;i<=n;i++){//求连通块并且标记 
        for(int j=1;j<=n;j++){
            if(a[i][j]=='#'){
                cnt++;
                dfs(i,j,cnt);   
            }
        }
    }
    
/*  for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            printf("%c",a[i][j]);
            if(j==n) printf("\n");
        }   
    }*/
        
    for(int i=1;i<=n;i++){//按照要求淹没陆地 
        for(int j=1;j<=n;j++){
            if(a[i][j]!='.'){
                for(int k=0;k<4;k++){
                    int tx=i+net[k][0];
                    int ty=j+net[k][1];
                    if(judge_border(tx,ty)&&a[tx][ty]=='.'){//一个陆地旁边有海洋就被淹没 
                        vis1[i][j]=1;
                        break; 
                    }
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(vis1[i][j]) a[i][j]='.'; 
            
    /*for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            printf("%c",a[i][j]);
            if(j==n) printf("\n");
        }       
    }
    */
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(a[i][j]!='.') s.insert(a[i][j]);
    printf("%d\n",cnt-'0'-s.size());
    return 0;
}   

转载于:https://www.cnblogs.com/zut-syp/p/10548247.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值