国外的网站需要备案吗,甘肃艾欧网络科技有限公司,湖州微信网站建设,中国建筑第八工程局官网目录 A - tmn学长的字符串1
B - 帮帮神君先生
C - z学长的猫
D - 这题用来防ak
E - 这题考察FFT卷积 F - 这题考察二进制 G - 这题考察高精度
H - 这题考察签到
I - 爱派克斯#xff0c;启动!
J - tmn学长的字符串2
K - 秋奕来买瓜 A - tmn学长的字符串1
思路#x…目录 A - tmn学长的字符串1
B - 帮帮神君先生
C - z学长的猫
D - 这题用来防ak
E - 这题考察FFT卷积 F - 这题考察二进制 G - 这题考察高精度
H - 这题考察签到
I - 爱派克斯启动!
J - tmn学长的字符串2
K - 秋奕来买瓜 A - tmn学长的字符串1
思路字符串模拟。
对于第一类字符串其组成一定是合法的数字第二类字符串则是其他剩余的情况。
对于字符串的处理我们开一个string去记录每段字符串对于一段字符串的记录因为会出现空串的情况所以我们在记录字符串时加入一个特殊符号在最后输出的时候特判即可。
因为是字符串模拟所以不涉及算法具体思路看代码注释
#include bits/stdc.h
using namespace std;
const int N 1e6 5;
typedef long long ll;
const int maxv 4e6 5;
typedef pairll, ll pll;bool check(string s)//判断是否为数字字符串
{for(int i0;is.size();i){if(s[0]0s.size()!1){return false;}if(s[i]0||s[i]9) return false;}return true;
}void solve()
{string s;cins;s;;vectorstring c1,c2;//使用vector去储存每个字符串string t;for(int i0;is.size();i){if(s[i],||s[i];){//我们把题目给定的,和;称为终止符当我们遇见终止符时就进行判断if(t.empty()) t.push_back(#);//如果当前用于储存的字符串t为空那么我们就放入一个特殊字符特殊字符只是用于应对空串的情况其他情况不会出现特殊字符if(check(t)){//去检验目前字符串是否合法c1.push_back(t);//合法即全为数字那么存入1}else{c2.push_back(t);//否则存入2}t;//将t清空}else ts[i];//如果当前不是终止符直接将该字符加入t即可}if(c1.size()){//因为c1是储存的数字所以不可能出现空串的情况cout\;for(int i0;ic1.size();i){coutc1[i];if(i!c1.size()-1) cout,;}cout\;}else{cout-;}coutendl;if(c2.size()){//c2储存的其他情况的字符串所以需要进行特判cout\;if(c2[0]!#) coutc2[0];//特判特殊字符for(int i1;ic2.size();i){cout,;if(c2[i]!#) coutc2[i];}cout\;}else{cout-;}coutendl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t 1;//cin t;while (t--){solve();}system(pause);return 0;
}
B - 帮帮神君先生
思路考察最基本的二分算法。把题意抽象一下就是对于每一个,求在a数组中有多少个比小的数因为a数组和b数组都是2e5的大小所以我们对于每一个每次去遍历一遍a数组会超时因为这时候我们的时间复杂度相当于是2e5*2e5而c一秒只能跑1e8左右所以需要算法对其进行优化。运用二分算法即可成功解决此题
#include bits/stdc.h
using namespace std;
const int N 1e6 5;
typedef long long ll;
const int maxv 4e6 5;
typedef pairll, ll pll;void solve()
{int n,m;cinnm;vectorint a(n),b(m);for(int i0;in;i) cina[i];for(int i0;im;i) cinb[i];sort(a.begin(),a.end());for(int i0;im;i){int tupper_bound(a.begin(),a.end(),b[i])-a.begin()-1;if(t0){coutt1 ;}else cout0 ;}coutendl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t 1;//cin t;while (t--){solve();}system(pause);return 0;
}
C - z学长的猫
思路题目要我们先删除但先排序后删除本质上是一样的所以先将数组进行排序由此此题转化为了在有序数组中寻找最大的一段符合条件的的区间即区间中后一个数减前一个的差不能超过k因为题目要求剩余区间全部合法所以我们只用求出最大合法区间然后把其他的全部删去就好。
#includebits/stdc.husing namespace std;
const int N1e55;
typedef long long ll;
typedef pairll,ll pll;void solve()
{ int n,k;cinnk;vectorint a(n5);for(int i1;in;i) cina[i];sort(a.begin()1,a.begin()1n);int cnt1;int res0;for(int i1;in;i){int xa[i1]-a[i];if(xk){cnt;}else{resmax(res,cnt);cnt1;}}resmax(res,cnt);coutn-resendl;}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;t1;cint;while(t--){solve();}system(pause);return 0;
}
D - 这题用来防ak
思路签到题判断最大的两个数相加是否大于等于10即可。
#includebits/stdc.husing namespace std;
const int N1e55;
typedef long long ll;
typedef pairll,ll pll;void solve()
{ int a,b,c;cinabc;vectorint s;s.push_back(a),s.push_back(b),s.push_back(c);sort(s.begin(),s.end());if(s[2]s[1]10) coutYESendl;else coutNOendl;}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;t1;cint;while(t--){solve();}system(pause);return 0;
}
E - 这题考察FFT卷积
思路将题意抽象为给定一个n要求输出1-n范围内只含有一个非0数字的个数。
我们从规律入手我们可以发现1-9的范围内有9个数1-9本身10-90的范围内有9个数 102030……90以此类推100到900之间也存在9个数我们可以发现9的个数是和n的位数挂钩的并且最高位为多少就会多加几个数字。因此我们可以将n的位数求出来并且求出n的最高位就可以得到答案。 其实我们发现如果是两位数的话最后的数字为从9开始加所以位数减一就为9的组数比如3位数就有2组9也就是18。此时刚好分解得到最高位再加上最高位就可以了。
#includeiostream
#includealgorithmtypedef long long ll;
const int N1e55;
using namespace std;int main()
{ int t;scanf(%d,t);while (t--){ int n;cinn;int cnt0;if(n9){coutnendl;continue;}while(n10){n/10;cnt;}coutncnt*9endl;} return 0;} F - 这题考察二进制
思路签到题按题意模拟即可。
#includebits/stdc.h
using namespace std;
const int N1e65;
typedef long long ll;
typedef pairll,int pll;void solve()
{int n;cinn;vectorint a(n);for(int i0;in;i) cina[i];int cnt0;for(int i0;in;i){int res0;if(a[i]0){for(int ji;jn;j){if(a[j]0){res;}else break;}cntmax(cnt,res);}}coutcntendl;}
int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t1;cint;while(t--){solve();}system(pause);return 0;
} G - 这题考察高精度
思路签到诈骗题其实根本用不上高精度我们求前n项和然后减去所有2的幂次方的两倍即可。
#includebits/stdc.h
using namespace std;
const int N1e55;
typedef long long ll ;
const int maxv4e65;
typedef pairll,ll pll;void solve()
{ll n;cinn;ll res(n1)*n/2;for(int i0;;i){ll x1lli;//求2的幂次方使用其他方法也可以比如循环或者直接调用pow函数if(xn) res-x*2;else break;}coutresendl;}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t1;cint;while(t--){solve();}system(pause);return 0;
}
H - 这题考察签到
思路二分答案防ak题
#include bits/stdc.h
using namespace std;
const int N 3e5 5;
typedef long long ll;
const int maxv 4e6 5;
typedef pairll, ll pll;
typedef arrayll,3 p3;ll n,m,k,s;
vectorint a(N),b(N);
vectorpll am(N),bm(N);
vectorpll w(N);bool check(int x)
{ll res0;vectorll v;for(int i0;im;i){auto [t,c]w[i];if(t1){v.push_back(am[x].first*c);}else{v.push_back(bm[x].first*c);}}sort(v.begin(),v.end());for(int i0;ik;i) resv[i];return ress;}void solve()
{cinnmks;int c2e9;int day1;for(int i1;in;i){cina[i];if(a[i]c){ca[i];dayi;}am[i]{c,day};}c2e9,day1;for(int i1;in;i){cinb[i];if(b[i]c){cb[i];dayi;}bm[i]{c,day};}for(int i0;im;i){int t,c;cintc;w[i]{t,c};}int l1,rn;int ans-1;while(lr){int mid(lr)/2;if(check(mid)){ansmid;rmid-1;}else{lmid1;}}if(ans-1){cout-1endl;return ;}coutansendl;vectorp3 v;for(int i0;im;i){auto [t,c]w[i];if(t1){v.push_back({am[ans].first*c,am[ans].second,i1});}else v.push_back({bm[ans].first*c,bm[ans].second,i1});}sort(v.begin(),v.end(),[](p3 x,p3 y){if(x[0]y[0]) return x[1]y[1];return x[0]y[0];});vectorpll cur;int cnt1;for(int i0;ik;i){auto [x,y,id]v[i];cur.push_back({id,y});cnt;}for(auto [x,y]: cur) coutx y\n;}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t 1;//cin t;while (t--){solve();}system(pause);return 0;
}
I - 爱派克斯启动!
思路签到。
统计每组的和是否大于等于2即可。
#includebits/stdc.husing namespace std;
const int N1e55;
typedef long long ll;void solve()
{ int cnt0;int n;cinn;for(int i0;in;i){int a,b,c;cinabc;if(abc2) cnt;}coutcntendl;}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;t1;//cint;while(t--){solve();}system(pause);return 0;
}
J - tmn学长的字符串2
思路字符串模拟。
将题意抽象一下给定一个字符串将指定区域的字符串循环移动k次。
因为k的范围位1e9所以不可能去一次次的进行暴力移动 我们可以发现当一个子串的循环移动次数为该串的长度时子串复原所以我们只需要去对子串进行k%len子串长度次的移动即可。
#includebits/stdc.h
using namespace std;
const int N1e55;
typedef long long ll ;
const int maxv4e65;
typedef pairll,ll pll;void solve()
{string s;cins;int q;cinq;while(q--){int l,r,k;cinlrk;int lenr-l1;k%len;string as.substr(0,l-1);string bs.substr(l-1,r-l1);string cs.substr(r);string xb.substr(0,len-k);string yb.substr(len-k);sayxc;}coutsendl;}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t1;//cint;while(t--){solve();}system(pause);return 0;
}
给出第二种题解
模拟操作把区间内的每个字母向右移动k位即可 假设区间为[1, 5]区间内字符串为12345 向右移动2位的话就是45123 向右移动5位的话还是12345相当于没变 所以向右移动7位和向右移动2位的效果是一致的 所以每次操作时先把k模一下区间长度即可
#includebits/stdc.h
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl \nusing namespace std;typedef pairint, int PII;
typedef long long ll;const int N 110;int main()
{IOSstring s;cin s;int Q;cin Q;while(Q --){int l, r, k;cin l r k;string tmp s;for(int i l; i r; i ){//ne表示移动后在字符串中所处的下标, i - l 表示在所选区间内的第几位 int ne l - 1 (i - l k) % (r - l 1);//(r - l 1)是区间长度,(i - l k) % (r - l 1)是移动后所处在区间中第几个位置(从0开始算) tmp[ne] s[i - 1];}s tmp;}cout s endl;return 0;
}
K - 秋奕来买瓜
思路签到判断奇偶即可注意特判2的情况。
#includeiostream
using namespace std;
typedef long long ll;int main()
{int n;cinn;if(n%2!0||n2){coutNOendl;}else{coutYESendl;}return 0;
}