蓝桥杯第二章:基础算法_2

1.区间次方和 - 蓝桥云课 (lanqiao.cn)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll p = 1e9 + 7;
const int N = 1e5 + 9;
ll a[6][N];
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n, m;cin >> n >> m;
    for (int i = 1; i <= n; i++){
        cin >> a[1][i];
    } // 先对第一个数组1次方进行赋值
    for (int i = 2; i <= 5; i++){
    for(int j=1;j <= n; j++){
            a[i][j] = (a[i - 1][j] * a[1][j]) % p;
        } // a[j]的i次方是a[j]的i-1次方*a[j]的1次方
    }
    // a[i][j]的值是通过将a[i][j]乘上a[1][j-1]上并对p取模得到的。
    // 其中,a[i][j-1]是上一个元素的值。
    for (int i = 1; i <= 5; i++){
        for (int j = 1; j <= n; j++){
            a[i][j] = (a[i][j - 1] + a[i][j]) % p;
        }
    }//将a数组覆盖了
    while (m--){
        int l, r, k;cin >> l >> r >> k;
        cout << (a[k][r] - a[k][l - 1] + p) % p << '\n';
    } //+p是为了防止负数取模
      // a[k][r]表示前缀和数组中第k数组前r个元素的和,
    //  a[k][l-1]表示前缀和数组中第k数组前l-1个元素的和,
    //  所以a[k][r]-a[k][l-1]就表示第k个数组第l到r个元素的和。
    return 0;
}

1.小郑的蓝桥平衡串 - 蓝桥云课 (lanqiao.cn) 

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1010;
int a[N];
int main()
{
    string s;cin>>s;
    for (int i = 1; i < s.size(); i++)
    {
        a[i] = a[i - 1] + (s[i] == 'L' ? 1 : -1);
    } // 记录下每一个的前面几项的和相当于数学数列中s1 s2.....
    // 计算字符串 s 中每个位置的前缀和的 prefix[0]=s[0]=0;
    // 假设 s="LLRRL",则 prefix 数组的值为 [1,2,1,0,-1],因为:
    // prefix[1] = 1,因为 s[1] 是 L;//带着本身
    // prefix[2] = 2,因为 s[1] 和 s[2] 都是 L;
    // prefix[3] = 1,因为 s[3] 是 R;
    // prefix[4] = 0,因为 s[4] 是 R,且前面有两个 L 和两个 R;
    // prefix[5] = -1,因为 s[5] 是 R,且前面有两个 L 和三个 R。
    // 三目运算符如果时L的话加1如果是Q的话-1
    int ans = 0;
    for (int i = 1; i <= s.size(); i++)
    {
        for (int j = 1; j <s.size(); j++)
        {                                       // 计算[i,j]中的符号
            if (a[j] - a[i - 1] == 0) // 注意是哪个-哪个
                ans = max(ans, j - i + 1);      // 不断更新长度
        }
    }
    // 这里的循环是枚举所有可能的子串,然后判断该子串的和是否为0,如果是,则更新答案。
    // prefix[j]-prefix[i-1]表示从i到j的子数组的和。如果prefix[j]-prefix[i-1](这是一个区间,长度为i-1-j)等于0,
    // 则说明从i到j的子数组的和为0,此时更新ans的值,使其等于当前子数组的长度j-i+1和ans中较大的那个值。
    cout << ans;
    return 0;
}//也可以覆盖原来的s数组

1.大石头的搬运工 - 蓝桥云课 (lanqiao.cn) 

#include<bits/stdc++.h>
#define ll long long
#define f first//重量
#define s second//位置
using namespace std;
ll ans = 0x3fffffffffffffff;
bool cmp(pair<ll,ll>a,pair<ll,ll>b){
  return a.s<b.s;
}
void solve(){
    // n:石头数量
    int n; cin >> n;
    vector< pair<ll,ll> > a(n + 1);
    // 前缀和,后缀和
    vector<ll> pre(n + 1,0),fin(n + 1,0);
    // 输入数对,将其存储在a[i]内
    for(int i = 0;i <n;i ++){
        int w,p;
        cin >> w >> p;//重量和位置
        a[i] = make_pair(w,p);
    }

    // 使用自定义函数对每个石头的位置进行排序
    sort(a.begin() ,a.end(),cmp);
    // tot: i 前所有石头的重量
    ll tot = 0;
    // 将 i 前所有石头搬到 i 处所需费用
    for(int i = 1;i < n;++ i){//从倒数第二个开始到最后一个
        tot += a[i - 1].f;//不断更新搬的石头的重量
        pre[i] = pre[i - 1] + tot * (a[i].s - a[i -1].s);
    }
    // tot: i 后所有石头的重量
     tot = 0;
    // 将 i 后所有石头搬到 i 处所需费用
    for(int i = n - 1;i >= 0;-- i){//从倒数第二个开始 到最后一个
        tot += a[i + 1].f;//不断更新石头的总重量
        fin[i] = fin[i + 1] + tot * (a[i + 1].s - a[i].s);
    }
    for(int i = 0;i < n;i ++){
        // 1ll 是一个类型转换操作符,用于将 int 类型的变量 i 转换为 long long 类型的变量
        ans = 1ll * min(pre[i] + fin[i],ans);
    }
    cout << ans << '\n';
}
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    solve();
    return 0;
}

蓝桥杯省赛无忧班(C&C++ 组)第 2 期 - 最大数组和 - 蓝桥云课 (lanqiao.cn) 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//不能贪心 只能枚举每种请情况 贪心连样例都过不去
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t;cin >> t;
    while(t--){
        int n, k;cin >> n >> k;
        vector<ll> a(n);
        for(int i = 0;i < n;i++) cin >> a[i];
        sort(a.begin(), a.end());
        for(int i = 1;i < n;i++) a[i] += a[i - 1];//a[1]表示的是index从0到1的和
        ll ans = 0;
        int pos = 0;
        while(k >= 0){//这里不是k,因为删除的个数可以为0
        //删除最大的元素的个数  最后一个元素是n-1,
            ans = max(ans, a[n - k-1] - a[pos-1]);
            pos += 2; 
            k--;
        }
        cout << ans << "\n";
    }
    return 0;
}

1.四元组问题 - 蓝桥云课 (lanqiao.cn) (未AC 只过了70代码)

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+9;
int a[N];
bool great( int n) {
    int val;
    return val < n;
}
int main(){
  int n;cin>>n;
  for(int i=1;i<=n;i++)cin>>a[i];
  for(int i=1;i<=n;i++){//选中了a[i]
    auto it=upper_bound(a+1,a+n+1,a[i]);
    if(it!=a+n+1){//选中了*it
    for(auto itt=++it;itt<a+n+1;itt++){
       if(*itt<*it){//选中
         if(find_if(itt+1,a+n+1,great)!=a+n+1){
           cout<<"YES";
           return 0;
         }
       }
    }
    }
  }
  cout<<"NO";
  return 0;
}

1.小明的彩灯 - 蓝桥云课 (lanqiao.cn) 

#include <bits/stdc++.h>
using namespace std;
const int N=1e6;
typedef long long ll;
int main(){
  ll a[N]={0},d[N]={0};
  ll n,q;cin>>n>>q;
  for(ll i=1;i<=n;i++){
    cin>>a[i];
    d[i]=a[i]-a[i-1];//实现差分!!记住!!
  }
  while(q--){
    ll l,r,x;cin>>l>>r>>x;
    d[l]+=x;
    d[r+1]-=x;//对d[i]操作会对d[i]后的所有数产生影响
  }
  for(ll i=1;i<=n;i++){
    // d[i]+=d[i-1];//相当于还原a数组 
    //a数组是d[i]的前缀和数组
    a[i]=a[i-1]+d[i];
    if(a[i]<0)cout<<0<<" ";
    else cout<<a[i]<<" ";
    }
  return 0;
}

2.肖恩的投球游戏加强版 - 蓝桥云课 (lanqiao.cn) 

#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int a[N][N]={0},d[N][N]={0};
void insert(int x1,int y1,int x2,int y2,int c){
  d[x1][y1]+=c;
  d[x2+1][y1]-=c;
  d[x1][y2+1]-=c;
  d[x2+1][y2+1]+=c;
}
int main(){
  int n,m,q;cin>>n>>m>>q;
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
        cin>>a[i][j];
        insert(i,j,i,j,a[i][j]);
    }
  }
  while(q--){
    int x1,y1,x2,y2,c;cin>>x1>>y1>>x2>>y2>>c;
    insert(x1,y1,x2,y2,c);
  }
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
      d[i][j]+=d[i-1][j]+d[i][j-1]-d[i-1][j-1];//还原差分数组
      cout<<d[i][j]<<" ";
    }
    cout<<'\n';
  }
  return 0;
}

 1.泡澡 - 蓝桥云课 (lanqiao.cn)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+2;
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  ll d[N]={0};//a数组初始是0的话不用构造差分数组,a数组也可以不要
  ll n,w;cin>>n>>w;
  ll lt=INT_MIN;
  while(n--){
    ll s,t,p;cin>>s>>t>>p;
    lt=1ll*max(lt,t);
    d[s]+=p;
    d[t]-=p;//开区间所以为t
  }
  for(ll i=1;i<lt;i++){//n是人数啊,这里应该遍历可以洗澡的时间啊啊啊不能乱带
    d[i]+=d[i-1];//还原原来的数组
  }
  for(ll i=0;i<lt;i++){
    if(d[i]>w){cout<<"No";return 0;}//必须分开遍历因为0也在范围内
  }
  cout<<"Yes";
  return 0;
}

1.谈判 - 蓝桥云课 (lanqiao.cn) 

#include <bits/stdc++.h>
using namespace std;
const int N=1002;
typedef long long ll;
int main()
{
  priority_queue<ll,vector<ll>,greater<int> >pq;
  //默认less排序 top在右 less在左
  int n;cin>>n;
  while(n--){
    int m;cin>>m;pq.push(m);
  }
  ll sum=0;
  while(pq.size()!=1){
    ll total=0;
    total+=pq.top();pq.pop();
    total+=pq.top();pq.pop();
    pq.push(total);
    sum+=total;
  }
  cout<<sum;
  return 0;
}

1.纪念品分组 - 蓝桥云课 (lanqiao.cn) 

#include <bits/stdc++.h>
using namespace std;
const int N=30006;
int memo[N]={0};
int main()
{
  int w,n;cin>>w>>n;
  for(int i=0;i<n;i++)cin>>memo[i];
  sort(memo,memo+n);
  int l=0,r=n-1;
  int cnt=0;
  while(l<=r){//最后一件了也要送出去啊啊
    if(memo[l]+memo[r]<=w)l++;
    r--;
    cnt++;
  }
  cout<<cnt<<'\n';
  return 0;
}

1.珠宝的最大交替和 - 蓝桥云课 (lanqiao.cn) 

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define all(s) s.begin(),s.end()
int n;
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  cin>>n;
  vector<LL>a,b;
  for(int i=1;i<=n;i++){
    LL x;cin>>x;
    x =abs(x);
    if(i%2==0)b.push_back(x);
    else a.push_back(x);
  }
  if(n==1){cout<<abs(a[0]);return 0;}
  LL mi=*min_element(all(a));
  LL mx=*max_element(all(b));
  LL ans=accumulate(all(a),0LL)-accumulate(all(b),0LL);
  if(mx>mi)ans+=2*(mx-mi);
  cout<<ans;
  return 0;
}

1.小蓝的礼物 - 蓝桥云课 (lanqiao.cn) 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+2;
ll a[N],prefix[N];
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  int n,m;cin>>n>>m;
  for(int i=1;i<=n;i++){
    cin>>a[i];
  }
  sort(a+1,a+n+1);
  for(int i=1;i<=n;i++){
    prefix[i]=prefix[i-1]+a[i];
  }//前缀和数组
  for(int i=1;i<=n;i++){//前i-1个礼物的和加上最后一个打折>m
    if(prefix[i-1]+ceil(1.0*a[i]/2)>m){cout<<i-1<<'\n';return 0;}
  }
  cout<<n<<'\n';
  return 0;

1.冒险者公会 - 蓝桥云课 (lanqiao.cn) 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+2;
int a[N],b[N][N],c[N];
ll ans=0;
//冒险者的能力 第i个村庄的第j个委托 第i个村庄的委托个数
void solve(){
  int m,n;cin>>m>>n;//输入冒险者的个数,和村庄数量
  multiset<int>s;
  for(int i=1;i<=m;i++){
    cin>>a[i];//输入冒险者的能力
    s.insert(a[i]);
  }
  int maxx=0;//记录一下所有村庄中委托最多的委托个数
  for(int i=1;i<=n;i++){
    cin>>c[i];//输入委托个数
    for(int j=1;j<=c[i];j++){
      cin>>b[i][j];
    }
    maxx=max(maxx,c[i]);//一个村庄最多maxx个任务
    sort(b[i]+1,b[i]+1+c[i],greater<int>());//大的往左边放
    //第1个委托是最难的
  }
  for(int i=1;i<=maxx;i++){//拿最大的任务数遍历每个村庄
    //枚举派出第i个冒险者要达成的条件
    int tmpmax=0;//当前轮完成的委托你拿度的最大值
    for(int j=1;j<=n;j++){//n个村庄
      tmpmax=max(tmpmax,b[j][i]);//记录第i个任务有多难
    }
    //需要满足第i个冒险者的能力值>=tmpmax
    auto it =lower_bound(s.begin(),s.end(),tmpmax);
    //代表第一个大于等于tmpmax的下标
    if(it==s.end()){//说明没有冒险者的能力大于等于tmpmax
      cout<<-1<<'\n';return ;
    }else{
      ans+=(*it);
      s.erase(it);
    }
  }
  cout<<ans<<'\n';
}
int main(){
  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  int t=1;
  while(t--){
    solve();
  }
  return 0;
}

1.明日方舟大作战! - 蓝桥云课 (lanqiao.cn) 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 2;
ll a[N], c[N], e[N];
ll dp[N]; // dp[j]代表花费为j的情况下能得到的最大攻击力
void solve() {
    int n, m, B;
    cin >> n >> m >> B;//输入船员 敌人 预算
    for (int i = 1; i <= n; i++) {
        cin >> a[i] >> c[i];
    }
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= n; i++) { // 遍历每一个船员
        for (int j = B; j >= c[i]; j--) { // 逆序枚举背包容量
            dp[j] = max(dp[j], dp[j - c[i]] + a[i]);
            // 比较选择和不选择第i个物品时的最大价值
        }
    }//bei
    int maxx = dp[B]; // 表示再花费为B的情况下能得到的船员最大攻击力
    int ans = 0;
    if(maxx==0){cout<<-1<<'\n';return ;}
    for (int i = 1; i <= m; i++) {
        cin >> e[i];
        int term = (e[i] + maxx - 1) / maxx;//取整
        ans = max(ans, term);
    }
    cout << ans << '\n';
}
int main() {
    solve();
    return 0;
}

 

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值