classSolution{public:int hash[100010]={0};intmaxLength(vector<int>& arr){int ret =1;int left =0;int right =0;while(right < arr.size()){
hash[arr[right]]++;while(hash[arr[right]]>1){
hash[arr[left]]--;
left++;}
ret =max(ret, right - left +1);
right++;}return ret;}};
#include<iostream>#include<vector>#include<algorithm>usingnamespace std;constint N =1e5+10;intmain(){longlong sum =0;int n =0;
cin >> n;longlong arr[N *3];for(int i =0; i <3* n; i++){
cin >> arr[i];}sort(arr, arr +3* n);for(int i =3* n -2; i >= n; i -=2){
sum += arr[i];}
cout << sum << endl;return0;}
#include<iostream>#include<unordered_map>usingnamespace std;boolcheck(unordered_map<int,int>& cnt,int x,int m)// 判断最多⼈数为 x 时,能否分成 m 组{int g =0;for(auto&[a, b]: cnt){
g += b / x +(b % x ==0?0:1);}return g <= m;}intmain(){int n, m;
cin >> n >> m;
unordered_map<int,int> cnt;// 统计每种声部的⼈数int hmax =0;for(int i =0; i < n; i++){int x =0;
cin >> x;
hmax =max(hmax,++cnt[x]);}int kinds = cnt.size();if(kinds > m){
cout <<-1<< endl;}else{// 暴力枚举// for(int i = 1; i < hmax; i++)// {// if(check(cnt, i, m))// {// cout << i << endl;// break;// }// }// 二分查找int left =1;int right = hmax;while(left < right){int mid =(left + right)/2;if(check(cnt, mid, m)){
right = mid;}else{
left = mid +1;}}
cout << left << endl;}return0;}
#include<iostream>#include<vector>#include<queue>usingnamespace std;constint N =2e5+10;
vector<vector<int>>edges(N);// edges[i] 表⽰ i 这个点所连接的边的信息int in[N];// 统计⼊度信息int n, m;
queue<int> q;
vector<int> ret;// 记录最终结果intmain(){
cin >> n >> m;while(m--){int a, b;
cin >> a >> b;
edges[a].push_back(b);// 存储边的信息
in[b]++;// 存储⼊度}for(int i =1; i <= n; i++)// 把⼊度为 0 的点放进队列中{if(in[i]==0){
q.push(i);}}while(q.size()){int a = q.front();
q.pop();
ret.push_back(a);for(auto& b : edges[a]){if(--in[b]==0){
q.push(b);}}}// 判断if(ret.size()== n){for(int i =0; i < n -1; i++){
cout << ret[i]<<" ";}
cout << ret[n -1];}else{
cout <<-1<< endl;}return0;}
4. Day16
4.1 字符串替换(模拟)
题目链接: QR6 字符串替换
题目描述:
解法:
算法思路:简单模拟题~
C++ 算法代码:
classStringFormat{public:
string formatString(string A,int n, vector<char> arg,int m){
string ret;int j =0;for(int i =0; i < n; i++){if(i +1< n && A[i]=='%'&& A[i +1]=='s'){
ret += arg[j++];
i++;}else{
ret += A[i];}}if(j < m){for(int i = j; j < m; j++){
ret += arg[i];}}return ret;}};
#include<iostream>#include<vector>#include<cmath>usingnamespace std;boolisprim(int n)// 判断是否是质数{if(n <2){returnfalse;}for(int i =2; i <=sqrt(n); i++)// 试除法{if(n % i ==0){returnfalse;}}returntrue;}intcheck(int n){
vector<int> nums;while(n){
nums.push_back(n %10);
n /=10;}for(int i =0; i < nums.size(); i++){for(int j =0; j < nums.size(); j++){if(i != j && nums[i]!=0){if(isprim(nums[i]*10+ nums[j])){return1;}}}}return0;}intmain(){int a, b;
cin >> a >> b;int ret =0;for(int i = a; i <= b; i++){
ret +=check(i);}
cout << ret << endl;return0;}
#include<iostream>usingnamespace std;intmain(){
string s;
cin >> s;for(longlong i =0; i < s.size(); i++){if((s[i]-'0')%2==1){
s[i]='1';}else{
s[i]='0';}}
cout <<stoi(s)<< endl;// ⾃动处理前导零return0;}
5.2 十字爆破(预处理 + 模拟)
题目链接: 十字爆破
题目描述:
解法:
算法思路:模拟即可,但是由于数据量过大,我们可以提前把每⼀行以及每⼀列的和存起来,方便统计总和。
C++ 算法代码:
#include<iostream>usingnamespace std;constint N =1e6+10;intmain(){longlong n, m;
cin >> n >> m;longlong row[N], col[N];longlong arr[n][m];for(int i =0; i < n; i++){for(int j =0; j < m; j++){scanf("%ld",&arr[i][j]);
row[i]+= arr[i][j];
col[j]+= arr[i][j];}}for(int i =0; i < n; i++){for(int j =0; j < m; j++){printf("%ld ", row[i]+ col[j]- arr[i][j]);}printf("\n");}return0;}
#include<iostream>#include<algorithm>usingnamespace std;constint N =2e5+10;intmain(){int n, k;
cin >> n >> k;
pair<int,int> arr[N];// <酸度,甜度>for(int i =0; i < n; i++){
cin >> arr[i].first;}for(int i =0; i < n; i++){
cin >> arr[i].second;}sort(arr, arr + n,[&](const pair<int,int>& a,const pair<int,int>& b){if(a.second != b.second){return a.second > b.second;}else{return a.first < b.first;}});longlong s =0;longlong t =0;for(int i =0; i < k; i++){
s += arr[i].first;
t += arr[i].second;}
cout << s <<" "<< t << endl;return0;}