首页 > 其他分享 >2024SMU蓝桥训练2补题

2024SMU蓝桥训练2补题

时间:2024-04-10 22:22:25浏览次数:13  
标签:f1t2 int sum 蓝桥 -- 2024SMU 补题 ans mp

C-密文搜索

思路:不难。

void solve(){           //C--密文搜索  可以不是字符串哈希--因为只需要知道相同长度字符串对字母出现情况,可以对字符串进行!!!排序!!!
    string str; cin>>str;
    int n,ans=0; cin>>n;
    unordered_map<string,int> mp;
    for(int i=1;i<=n;i++){
        string x; cin>>x;
        sort(x.begin(),x.end());    //对字符串进行排序!!!
        mp[x]++;
    }
    for(int i=0;i<str.size()-7;i++){
        string x=str.substr(i,8);
        sort(x.begin(),x.end());
        ans+=mp[x];
    }
    cout<<ans;
}

D-交换次数

思路:十分有技巧!首先最终结果有6种,要对六种可能枚举,这个是容易想到的。

但是怎么检查某种排列的代价?

已知A,B,T各自出现的次数,那么枚举那种情况,就知道哪种情况最终具体是什么样的。

例如:输入 TTA BBT BAATT

情况BAT: BBB AAA TTTTT

定义f1t23,f1t2--f2t1,f2t3,含义为,第一部分要换到2,3部分的个数,第一部分要换到第2部分的个数--第二部分要换到第一部分的个数,第二部分要换到第三部分的个数。

第3部分不用管,因为前面两部分换好了,第3部分必然也换好了。

考虑3种情况:

①f1t2==f2t1:这种情况最好考虑:cost=f1t23+f2t3

②f1t2>f2t1:这种情况也比较好考虑,先把f2t1换了,再换多余的f1t2,,和换f1t3和f2t3:cost=f1t23+f2t3

③f1t2<f2t1:这种情况因为没有记录第三部分的情况,所以相对比较绕:cost=f1t23-f1t2+f2t1+f2t3--这里的f1t23-f1t2=f1t3,即cost=f1t3+f2t1+f2t3

第三种情况先f1t3是为了把在第三部分的,第二部分的字母,换到第一部分,然后进行f2t1的时候就可以换上。

string str;
int n,ans=INT_MAX,cnt[3];
unordered_map<char,int> mp;
string pos[6]={"ABT","ATB","BAT","BTA","TAB","TBA"};
void check(char a,char b,char c){
    int f1t23=0,f1t2=0,f2t1=0,f2t3=0;
    for(int i=0;i<cnt[mp[a]]+cnt[mp[b]];i++){
        if(i<cnt[mp[a]]){
            if(str[i]!=a) f1t23++;
            if(str[i]==b) f1t2++;
        }
        else{
            if(str[i]==a) f2t1++;
            if(str[i]==c) f2t3++;
        }
    }
    if(f1t2==f2t1) ans=min(ans,f1t23+f2t3);
    else if(f1t2>f2t1) ans=min(ans,f1t23+f2t3);
    else ans=min(ans,f1t23-f1t2+f2t1+f2t3);
}
void solve(){               //补D--交换次数--nb
    //枚举6种情况容易想到,问题是怎么check某种情况下的代价。
    cin>>str; n=str.size();
    mp['A']=0,mp['B']=1,mp['T']=2;
    for(int i=0;i<n;i++){
        if(str[i]=='A') cnt[mp[str[i]]]++;
        else if(str[i]=='B') cnt[mp[str[i]]]++;
        else cnt[mp[str[i]]]++;
    }
    for(int i=0;i<6;i++) check(pos[i][0],pos[i][1],pos[i][2]);
    cout<<ans;
}

E-k倍区间

思路:错了又错的老题。。见注释。

void solve(){           //补E--K倍区间--在牛客还是cf,做过一模一样的题目,当时也是补的题。现在再遇到,还是没想到,还是补题。。
    //前缀和pre;
    //如果某个区间[L,R]的和是K的倍数;
    // 那么(pre[R]-pre[L-1])%k=0;
    //pre[R]%k-pre[L-1]%k=0;
    //pre[R]%k = pre[L-1]%k;
    //答案显而易见,只需记录前缀和中出现相同余数的数字,两两配对的对数即是ans;
    int n,k,ans=0; cin>>n>>k;
    int sum=0;
    unordered_map<int,int> mp;
    //mp[0]=1;           //init
    for(int i=1;i<=n;i++){
        int x; cin>>x;
        sum=(sum+x)%k;
        ans+=mp[sum];         //到目前,前面有几个现在这个余数,就可以构成几个合法区间.
        if(sum==0) ans++;    //sum刚刚好为0的时候,代表这个区间不用减去前面某段,从1到cur刚刚好是k的倍数。当然也可以减去前面某段,就是减去前面也是0的区间。
        mp[sum]++;          //这个余数出现次数加一
    }
    cout<<ans;
}
void solve(){           //补E--K倍区间--在牛客还是cf,做过一模一样的题目,当时也是补的题。现在再遇到,还是没想到,还是补题。。
    int n,k,ans=0; cin>>n>>k;
    int sum=0;
    unordered_map<int,int> mp;
    for(int i=1;i<=n;i++){
        int x; cin>>x;
        sum=(sum+x)%k;
        mp[sum]++;          //这个余数出现次数加一
    }
    for(int i=0;i<k;i++) ans+=(mp[i]*(mp[i]-1)/2);   //组合--Cm2:m个中选两个配对;Cm2=m*(m-1)/2;
    ans+=mp[0];   //刚刚好为0的时候,代表这个区间不用减去前面某段,从1到cur刚刚好是k的倍数。当然也可以减去前面某段,就是减去前面也是0的区间(上面循环已经算过了).
    cout<<ans;
}

G-包子凑数

思路:正解是类似背包的dp,我的写法不是正解,但是类似。

void solve(){               //G--包子凑数  siwei?
    //似乎不是正解...要设好参数范围
    //一开始用vector来维护能组合出来的数字。
    //但是判断一个数x的能否被组合出来时,时间复杂度过高--用两层循环枚举vct所有数字组合---o(n^2)。
    //改成了set之后,既避免了重复数字,还能o(nlogn)复杂度下判断x能否被组合出来
    //参数范围ok的话,可以AC
    int n; cin>>n;
    set<int> st;
    int minn=200;
    bool checkone=false;
    for(int i=1;i<=n;i++){
        int x; cin>>x;
        st.insert(x);
        minn=min(minn,x);
        if(x==1) checkone=true;
    }
    if(checkone){
        cout<<"0";
        return;
    }
    int ans=0;
    set<int> test;
    st.insert(0);  //便于查找本身存在于st的x
    for(int x=1;x<=10000;x++){      //参数范围--1000太小,会wa两个点--5,6,7,8,9000太小,wa一个点--10000够了
        bool check=false;
        for(auto s:st){
            if(st.find(x-s)!=st.end()){
                st.insert(x);
                check=true;
                break;
            }
        }
        if(!check) {
            test.insert(x);
            ans++;
        }
    }
    bool check=false;
    int cur=1;
    for(auto p=st.begin();p!=st.end();p++){
        if(p==st.begin()) continue;
        if(*p-*prev(p)==1) cur++;
        else cur=1;
        if(cur==minn){          //判断能组合出来的数字,是否有minn个连续的数字,有的话后面所有数字都可以推出来。
        //--否则可以判定为INF,虽然不是完全严谨,但是在搜索1e4个数字后还没有连续minn个数字,就认为是INF了
            check=true;
            break;
        }
    }
    if(check) cout<<ans;
    else cout<<"INF";
}

 

标签:f1t2,int,sum,蓝桥,--,2024SMU,补题,ans,mp
From: https://www.cnblogs.com/ouhq/p/18127629

相关文章

  • P8791 [蓝桥杯 2022 国 AC] 内存空间 题解
    题面一道比较简单模拟题,但是要分类讨论一.读完题你应该知道的1.输入一共有T+1行,输入含有空格。(处理1)2.对于每一行变量定义的语句,只会出现一种变量类型,type只可能是int或long,只有一个分号。(处理1,处理2)3.统计内存过程中用B做单位,保证一定有输出,但在输出时要换......
  • P8779 [蓝桥杯 2022 省 A] 推导部分和
    并查集板子题#include<bits/stdc++.h>#defineR(x)x=read()#defineRLL(x)x=readLL()usingnamespacestd;typedeflonglongLL;constintN=1e5+5;inlineintread(){intx=0,f=1;charch=getchar();while(ch<'0'|......
  • 蓝桥杯单片机基于西风模板超声波底层
    超声波是外设需要重新自己编写c文件和h文件在c文件中需要编写两个函数一个是波的初始化一个是方波的读取voidWave_Init(){unsignedchari;for(i=0;i<8;i++){TX=1;发送信号Delay(12)us哦Tx=0在延时12us}这样波的初始化就好了}unsignedcharWave_Read(){unsig......
  • 蓝桥杯STM32G431RBT6-各个外设的配置过程
    LED,按键配置LED点亮,按键采集按键值前期准备:通过Cubemx生成一个源文件方便后续直接使用。  源文件准备完毕以后开始进行按键和LED的配置LED对比芯片引脚连接图可以知道8个LED分别连接在GPIOC的如下8个引脚中      Cubemx中......
  • 蓝桥杯-N皇后
    0.题目【题目描述】有一个N*N的矩阵棋盘和N个棋子,现在需要将N个棋子按要求放置在矩阵方格中。要求:1、任意两颗棋子不能在同一行2、任意两个棋子不能在同一列3、任意两个棋子不能在同一对角线上(下面的红线都是对角线)根据以上要求,问N个棋子放置到N*N矩阵中有多少种放置方案......
  • P8661 [蓝桥杯 2018 省 B] 日志统计 题解
    好久没写题解了,水一篇。这里主要想讲的是不同的处理方法,在阅读本篇题解前请确保读完题。详解一,排序这很好理解,题目要求将热帖从小到大输出,同时题目中还有相对的时间这一概念,因此将输入的\(id\)与\(ts\)按照优先\(id\)其次\(ts\)的排序方式从小到大,排序,这样输出时就没......
  • 蓝桥杯真题代码记录(最优清零方案
    目录1.题目:2.我的代码:小结:1.题目:给定一个长度为N的数列41,42,…,AN。现在小蓝想通过若干次操作将这个数列中每个数字清零。每次操作小蓝可以选择以下两种之一:1.选择一个大于0的整数,将它减去1;2.选择连续区个大于0的整数,将它们各减去1。小蓝最少经......
  • 第十一届蓝桥杯C/C++组C组决赛之思维风暴 快速解题
    十五届蓝桥杯即将开赛,十一届的蓝桥杯国赛的一些巧妙解法。美丽的2 题目描述本题为填空题,只需要算出结果后,在代码中使用输出语包将所填结果输出即可。小蓝特别喜欢2,今年是公元2020年,他特别高兴。他很好奇,在公元1年到公元2020年(包含)中,有多少个年份的数位中包含数字2?......
  • Acwing2024蓝桥杯DFS
    模板:AcWing826.单链表利用数组创建单链表:#include<iostream>usingnamespacestd;constintN=100005;inthead,value[N],nextt[N],id;voidInit(){head=-1,id=0;}voidHead_Insert_x(intx){value[id]=x;nextt[id]=head;head=id++;}voidD......
  • 杨辉三角形(蓝桥杯,acwing)
    题目描述:下面的图形是著名的杨辉三角形:如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:1,1,1,1,2,1,1,3,3,1,1,4,6,4,1,...给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数?输入格式:输入一个整数 N。输出格式:输......