【蓝桥杯】——>进制转换、前缀和、双指针[滑动窗口]

学会使用sort函数进行灵活判断

1.确定字符串是否包含唯一字符

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int  main(){
	string s;
	cin>>s;
	sort(s.begin(),s.end());
	int flag = 1;
	int n = s.size();
	for(int i = 0; i < n; i++){
		if(s[i]==s[i+1]) flag = 0;
	}
	if(flag){
		cout<<"YES";
	}
	else{
		cout<<"NO";
	}
	return 0;
}

一、进制的转换

eg1

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 50;
int a[N];
int main(){
	string s = "2021ABCD";
	int n = s.length();
	for(int i = 0; i < n; i++){
		if('0' <= s[i] && s[i] <= '9') a[i] = s[i] - '0';
		else a[i] = s[i] - 'A' + 10;
	}
	ll res = 0;
	for(int i = 0 ;i < n; i++){
		res = res * 16 + a[i];
	}
	cout << res << '\n';
	return 0;
}

或者使用0x2021ABCD

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

using ll = long long;
int main(){
  ll res = 0x2021ABCD;
  cout<<res;
  return 0;
}

归纳可得到任意进制转换为十进制的通用解法

eg2

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 50;
int a[N];
using ll = long long;

int main(){
  string s = "2022";
  int n = s.length();
  for(int i = 0; i < n; i++){
    a[i] = s[i] - '0';
  }
  ll res = 0;
  for(int i = 0; i < n; i++){
    res = res * 9 + a[i];
  }
  cout<<res<<'\n';
  return 0;
}

eg3 N进制转换为M进制

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 1000;
int a[N];
char ch[] = {'0', '1','2', '3','4', '5', '6', '7', '8', '9', 'A', 'B','C','D','E','F'};
void fun(){
  int n,m;
  string s;
  cin>> n>> m;
  cin>>s;
  int len = s.length();
  for(int i = 0; i < len; i ++){
    if('0' <= s[i]&& s[i] >= '9') a[i] = s[i] - '0';
    else a[i] = s[i] - 'A' + 10;
  }
  ll res = 0;
  for(int i = 0; i < n; i++){
    res = res * n + a[i];
  }
  string st;
  while(res){
    st += ch[res % m];
    res /= m;
  }
  reverse(st.begin(),st.end());
  cout<< st <<'\n';
  return ;
}
int main(){
  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  int n;
  cin>>n;
  for(int i = 0; i < n; i++){
   fun();
  }
  return 0;
}

我们可以得到十进制转为其他进制的解法以及任意进制转换为任意进制的通用结论

二、前缀和

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 1e5 + 5;
const int mod = 1e9 + 7;
ll a[N];  
ll pf[N][6];//前缀和数组
int n, m, l ,r, k;
int main(){
  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);

  cin>> n >> m;
  for(int i = 1 ;i <= n; i++){
    cin >> a[i];
    for(int j = 1; j <= 5 ; j++){
      pf[i][j] = pf[i - 1][j] + pow(a[i],j);
    }
  }
  while(m--){
      cin>>l>>r>>k;
      cout << (pf[r][k]-pf[l-1][k] + mod) % mod << '\n';//先+mod是为了处理负数的情况
    }
  return 0;
}
cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1005;

int main(){
  string s;  
 
  cin>> s;
  int n = s.length();  
  vector<int> pf(n+1,0);
  for(int i = 1 ; i <= n; i++){
    if(s[i - 1] == 'L') pf[i] = pf[i - 1] + 1;
    else pf[i] = pf[i - 1] - 1;
  }

  int ans = 0;
  for(int i = 1; i <= n; i++){
    for(int j = i; j <= n; j++){
      if(pf[j] - pf[i - 1] == 0) ans = max(ans,j - i + 1);
    }
  }
  cout<<ans<<'\n';
  return 0;
}

双指针(反转字符串、回文)

对撞指针

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
  string s;
  cin>> s;
  int flag =  1;
  int n = s.length();
  int l = 0, r = n - 1;
  while(l < r){
    if(s[l] == s[r]){
      l++;
      r--;
    }
    else {
      flag = 0;
      break;
    }
  }
  if(flag) cout<<"Y";
  else cout<<"N";
  return 0;
}

快慢指针

前缀和+快慢指针

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

int main(){
    int n;      // 序列长度
    ll s;       // 目标和阈值S
    cin >> n >> s;
    
    vector<ll> a(n);  // 输入序列,大小为n
    for(int i = 0; i < n; i++) cin >> a[i];  // 读入序列元素
    
    // 构建前缀和数组,pf[i]表示前i个元素的和
    vector<ll> pf(n+1, 0);  // 初始化为0
    for(int i = 0; i < n; i++){
        pf[i+1] = pf[i] + a[i];  // pf[i+1] = a[0] + a[1] + ... + a[i]
    }

    int l = 0, r = 0;           // 双指针,维护滑动窗口 [l, r)
    int ans = n + 1;            // 记录最短区间长度,初始化为不可能的值
    
    while(r <= n){              // 当右指针未越界时继续
        ll sum = pf[r] - pf[l]; // 计算区间 [l, r) 的和,即 a[l] + ... + a[r-1]
        
        if(sum >= s){           // 如果当前区间和大于等于S
            ans = min(ans, r - l);  // 更新最短长度,区间长度为 r - l
            l++;                // 尝试缩短区间,左指针右移
        }
        else {                  // 如果当前区间和小于S
            r++;                // 扩大区间,右指针右移
        }
    }
    
    if(ans == n + 1) cout << 0 << endl;  // 如果ans未被更新,说明没有满足条件的区间
    else cout << ans << endl;            // 否则输出最短区间长度
    
    return 0;
}

滑动窗口

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+9;
int a[N];
int main(){
	int n,s;
	cin>>n>>s;
	for(int i = 0; i< n;i++) cin>> a[i];
	int l = 0,r = 0;
	int w_sum = 0;
	int ans = n + 1;
	while(r<n){
		w_sum += a[r];
		while(w_sum >= s){
			ans = min(ans,r - l + 1);
			w_sum -= a[l];
			l++;
		}
		r++;
	}
	cout<<(ans == n+1?0:ans);
	return 0;
}
相关推荐
wuqingshun3141592 小时前
蓝桥杯 魔法蘑菇
职场和发展·蓝桥杯
z20348315202 小时前
17届蓝桥杯嵌入式赛道开发板外设使用教程——按键、蜂鸣器、LCD屏幕
mongodb·职场和发展·蓝桥杯
逆境不可逃2 小时前
LeetCode 热题 100 之 763.划分字母区间
算法·leetcode·职场和发展
wuqingshun3141592 小时前
蓝桥杯 无影之谜
算法·职场和发展·蓝桥杯
逆境不可逃3 小时前
【从零入门23种设计模式17】行为型之中介者模式
java·leetcode·microsoft·设计模式·职场和发展·中介者模式
Eward-an3 小时前
LeetCode 1009. 十进制整数的反码(详细技术解析)
算法·leetcode·职场和发展
筱昕~呀3 小时前
冲刺蓝桥杯-BFS板块(第八天)
职场和发展·蓝桥杯·宽度优先
仰泳的熊猫3 小时前
题目2086:蓝桥杯算法提高VIP-最长公共子序列
数据结构·c++·算法·蓝桥杯·动态规划
2301_8008951012 小时前
BFS--备战蓝桥杯版h
算法·蓝桥杯·宽度优先