A题.[蓝桥杯 2013 省 B](补题)

题意: 用1-9的不重复不遗漏的数字组成a,b,c,使得a+b/c=n成立,则是一种方案,求整数n可以有多少种方案组成

思路: _数组a为1-9,用nextpermutation函数暴力枚举出所有1-9的不重复的组合,然后将他们分开组成a,b,c,由于数据是<=10^6,因此a只需要枚举到7位数。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,num[9]={1,2,3,4,5,6,7,8,9},ans;
int  ZH(int s,int k ){
    int ma=0;
    for(int i=s;i<=k;i++){
        ma=ma*10+num[i];
    }
    return ma;
}
int main(){
    cin>>n;
    do {
        for (int i = 0; i <7; ++i) {
            for (int j = i+1; j <8 ; ++j) {
                int a,b,c;
                a= ZH(0,i);
                b=ZH(i+1,j);
                c=ZH(j+1,8);
                if((n-a)*c==b)
                    ans++;
            }
        }
    } while (next_permutation(num,num+9));
    cout<<ans;
    return 0;
};

B [蓝桥杯 2013 省 AB] 错误票据.(补题)


题意:给出若干个数,其中只有一个值出现了两次,除一个值没出出现外其他值均连续

思路:注意到n很小,读入后排序然后枚举一边即可。此题有一个读入的问题不太好处理,可以用while(cin>>a)或者while(scanf("%d", %a) !=EOF),读到错误会自动跳出循环。

代码:



#include <bits/stdc++.h>
using namespace std;
int n,a[100009],x,dh,ch;
int main(){
    cin>>n;
    vector<int>ve;
    while(cin>> x){
        ve.push_back(x);
        a[x]++;
    }
    for (int i = 1; i <=100000 ; ++i) {
        if(a[i]==0&&a[i+1]>0&&a[i-1]>0)
            dh=i;
        if(a[i]>1)
            ch=i;
    }
    cout<<dh<<' '<<ch;

}

C [蓝桥杯 2013 省 B] 翻硬币

题意: 两列硬币,每次操作可改变两个相邻硬币的正反,通过最小的n次把两列硬币变成完全相同

思路:题目保证一定有解,所以两个串的相同位置的不同情况一定出现偶数次,两两匹配算出花费即可

代码:


#include <bits/stdc++.h>
using namespace std;
string a,b;
int vis[1000],k,s;
int main(){
    cin>>a>>b;
    for (int i = 0; i <a.size() ; ++i) {
        if(a[i]!=b[i])
            vis[k]=i,k++;
    }
    for (int i = 0; i < k; i+=2) {
        s+=(vis[i+1]-vis[i]);
    }
    cout<<s;
}

E.P8683 [蓝桥杯 2019 省 B] 后缀表达式(补题)

题意:给n个+号,m个-号,n+m+1个数,求他们组合的最大的后缀和

思路:括号是任意加的,因此减法可以变成加法,例如:a-(b-c)=a+c-b,有减号,必然有一个数是被减,那么我们用最小的那个数来做被减,最大-最小+其他所有数的绝对值即可。

代码:


#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll s,k;
int n,m;
int main(){
    cin>>n>>m;
    vector<int>a(n+m+1);
    for (int i = 0; i <n+m+ 1 ; ++i) {
        cin>>a[i];
    }
    if(!m){
        for (int i = 0; i <n+m+1 ; ++i) {
            s+=a[i];
        }
        cout<<s;
        return 0;
    }
    sort(a.begin(),a.end());
    s=a[n+m]-a[0];
    for (int i = 1; i < n+m; ++i) {
        s+=abs(a[i]);
    }
    cout<<s;
}

F.P8682 [蓝桥杯 2019 省 B] 等差数列

题意:给定一个等差数列的部分n个数,求包含这n个数的最短的等差数列的个数

思路:

思路1:

排序求这n个数的差放入数组,求这个数组所有数字的最小公因数,既是最小公差。

思路2:

由于n个数都是等差数列的一部分,因此他们的差最小值必定是满足最短数列的最小公差。

提示注意:如果方差d是0,那么最小的个数即是n,不能用(Amax-Amin)/d+1来求

代码:

思路1

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[100005],b[100005];
int n,d;
ll gcd(ll n,ll m);
ll gcds(ll b[], ll m);
int main(){
    cin>>n;
    for (int i = 0; i <n ; ++i) {
        cin>>a[i];
    }
    sort(a,a+n,less<ll >());
    for (int i = 0; i <n-1; ++i) {
        b[i]=a[i+1]-a[i];
        if(b[i]==0) {
            cout <<n;
            return 0;
        }
    }
    ll k;
    k=gcds(b,n-1);
    cout<<(a[n-1]-a[0])/ k+1;
}
ll gcds(ll b[], ll m) {
    ll tem = b[0];
    for (int i = 1; i < m; i++) {
        tem = gcd(tem,b[i]);
    }
    return tem;
}
ll gcd(ll n,ll m){
    if(n % m == 0){
        return m;
    }
    return gcd(m,n%m);
}

思路2

    void solve() {
        cin >> n;
        vector<int> ve(n);
        for (int i = 0; i < n; i++) {
            cin >> ve[i];
        }
        std::sort(ve.begin(), ve.end());
        a = inf;
        for (int i = 0; i < n-1; ++i) {
            a = min(ve[i+1] - ve[i], a);
        }
        if (a == 0) {
            cout << n << '\n';
            return;
        }
        cout << (ve.back() - ve[0]) / a + 1 << '\n';

    }

G [蓝桥杯 2019 省 B] 特别数的和


题意:1-n中含有2,0,1,9任意数字的数字个数有多少?

思路:暴力枚举即可.

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int Num_number(int a)  //求数字位数
{
    int count=0;
    if(a==0) count=1;
    while(a!=0)
    {
        a/=10;
        count++;
    }
    return count;
}
int main(){
    ll n,s;
    cin>>n;
    for (ll i = 1; i <=n ; ++i) {
        int k;
        k= Num_number(i);
        ll a=i;
        int gg=0;
        while(k--){
            int x;
            x=a%10;
            a/=10;
            if(x==2||x==0||x==1||x==9) {
                gg=1;
                break;
            }
        }
        if(gg)
            s+=i;
    }
    cout<<s;
}


H [蓝桥杯 2019 省 AB] 完全二叉树的权值

题意:给出一颗包含n个节点的完全二叉树,问哪一层的权值之和最大

思路:把树每一层的号码的临界节点找出,由于n<=10^5,因此找到30层即可,再把每个节点的权值的枚举即可

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int to[30];
ll s[30],ss;
int n,g[100005],z;
int main(){
    to[0]=1;
    for (int i = 1; i <=30 ; ++i) {
        to[i]=to[i-1]*2;
    }
    cin>>n;
    int k=1;
    for (int i = 1; i <=n ; ++i) {
        cin>>g[i];

    }
    for (int i = 1; i <= n; ++i) {
        if(i<to[k]){
            s[k]+=g[i];
        }
        if(i==to[k]) {
            k++;
            s[k]+=g[i];
        }
    }
    for (int i = 1; i <=k ; ++i) {
        if(s[i]>ss){
            ss=s[i];
            z=i;
        }
    }
    cout<<z;
}

P8684 [蓝桥杯 2019 省 B] 灵能传输


代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll s[300005];// //前缀和,还要存S0,各元素初值为0
ll x,z,t,n;
int main(){
    cin>>t;
    while (t--){
        x=0;
        cin>>n;
        s[0]=0;
        for (int i = 1; i <=n ; ++i) {
                cin>>s[i];
            s[i]+=s[i-1];
        }
        if(s[0]>s[n])
            swap(s[0],s[n]);
        ll s0=s[0],sn=s[n];
        sort(s,s+n+1);
        for (int i = 0; i <=n ; ++i) {   // //找S0的位置(如果有多个值为S0,则任意取一个即可)
            if(s[i]==s0){
                s0=i;
                break;
            }
        }
        for (int i = 0; i <=n ; ++i) { //找Sn位置
            if(s[i]==sn){
                sn=i;
                break;
            }
        }
        vector<ll>a(n+1);        //存处理后的前缀和序列
        vector<bool>vis(n+1);       //排序后每个数取出与否的标志
        ll l=0,r=n;
        for (ll i = s0; i >=0 ; i-=2) {    //让S0跳着走到最小值S[0]

            a[l++]=s[i];
                vis[i]= true;
        }
        for (int i = sn; i <=n ; i+=2) {    //让Sn反跳着走到最大值S[n]
                a[r--]=s[i];
                vis[i]= true;
        }
        for (int i = 0; i <=n ; ++i) {    //剩下的数按顺序取
            if(!vis[i])
                a[l++]=s[i];
        }
        for (int i = 1; i <=n ; ++i) {
            x= max(x,abs(a[i]-a[i-1]));
        }
        cout<<x<<'\n';

    }
}
posted on 2023-01-04 00:47  IR101  阅读(12)  评论(0编辑  收藏  举报  来源