蓝桥杯做题笔记,经验和常见题型

1)求和

两两相乘,在求和

表面上看这是一道暴力求和的题,用两层循环。但是实际上是这是一道 前缀和的题目。暴力会超时。

解题思路,每个数都要乘与比自己大的数。换个角度看就是每个数都要乘与比自己小的数,二者等价。正好可以用前缀和求解。

#include <iostream>
#define MAXN 200001
using namespace std;
long long n,ret=0;//注意题目说了选择合适的数据类型
long long num[MAXN],sum[MAXN];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>num[i];
        sum[i]=sum[i-1]+num[i];
    }
    for(int i=2;i<=n;i++){
        ret+=(sum[i]-num[i])*num[i];
    }
    cout<<ret;
}

2)赢球票

该题通过遍历所有可能的起点,通过一个计数器累加,注意用vis数组来表示该牌有没有被取走

#include <bits/stdc++.h>
using namespace std;
int num[101];
int vis[101];
int main(){
    int n,ret=0;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>num[i];
    }
    for(int i=1;i<=n;i++){
        int count=0,cnt=1,x=i,ans=0;//设置count用来记录取走的个数,cnt报数器
        memset(vis,0,sizeof(vis));
        while(1){
            if(!vis[x]){
                if(num[x]==cnt){
                    ans+=cnt;
                    count++;
                    cnt=0;
                    vis[x]=1;
                }
                cnt++;
            }
            x++;
            if(x==n+1)x=1;
            if(count==n|cnt>n)break;//注意跳出循环的条件
        }
        if(ans>ret)ret=ans;
    }
    cout<<ret;
}

3)解迷游戏

这道B组国赛题,实际上只要观察出原理,就不难写出代码。

通过轮转我们可以发现,内圈0位置的塑料棒只能和外圈的三个塑料棒交换,只能和中圈的两个塑料棒交换

如图:

因此我们只需遍历内圈四根塑料棒,判断每一种情况下这六根塑料棒是否满足3绿2红1黄,如不满足则直接输出“NO”。

这里用到一个小技巧用一个数组---“桶”来记录不同颜色塑料棒出现的次数。

#include <bits/stdc++.h>
using namespace std;
int ret[100];
int main(){
    int T;
    cin>>T;
    while(T--){
        string a,b,c;
        bool flag=true;
        cin>>a>>b>>c;
        memset(ret,0,sizeof(ret));
        for(int i=0;i<4;i++){
            ret[a[i]]++;
            ret[b[i]]++;
            ret[c[i]]++;
            ret[a[i+4]]++;
            ret[a[i+8]]++;
            ret[b[i+4]]++;
            if(ret['G']!=3||ret['R']!=2||ret['Y']!=1){
                flag=false;
                break;
            }
        }
        if(flag){
            cout<<"YES"<<"\n";
        }else cout<<"NO"<<"\n";
    }
}

4)双子数

首先确定p,q的取值范围,由平方可知。p,q肯定小于23333333333333的开放,取值大约在1~1e7左右。

在1~1e7中筛选质数,可以用埃氏筛”

已知任何一个和数都有一个质因数小于该和数的开方,因此我们只需要筛选出“1e7开方”中的素数就可以遍历出所有在1e7中的和数,从而只剩下质数

long long a = 2333, b = 23333333333333, ret = 0;
        for (int i = 2; i <=sqrt(N); i++) {//筛选出该范围的质数
            if (cnt[i] == 0) {若为质数
                for (int j = i * i; j <= N; j += i) {
//开始筛选和数,至于为什么不从2*i开始筛选是因为,2以前已经作为i被筛选过了
                    cnt[j] = 1;
                }
            }
        }
        int cur = 0;
        for (int i = 2; i <= N; i++) {
            if (!cnt[i])isprime[cur++] = i;//将素数加入数组
        }
        for (int i = 0; i < cur; i++) {
            long long p1 =1LL* isprime[i] * isprime[i];
            if (1LL*p1 * p1 > b)break;
            for (int j = i + 1; j < cur; j++) {
                long long p2 =1LL*isprime[j] * isprime[j];
                if (1LL*p1 * p2 < a)continue;
                if (1LL*p1 * p2 > b)break;
                ret++;
            }
        }
        cout << ret;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值