AC代码:
- #include
- #include
- #include
- using namespace std;
- int main()
- {
- int n;
- cin>>n;
- for(int i=0;i
- int x;
- cin>>x;
- if(x%2==0)cout<
" "; - }
- return 0;
- }
AC代码:
- #include
- #include
- #include
- #include
- using namespace std;
- const int N=110;
- int a[N][N];
- int main()
- {
- int h,w;
- cin>>h>>w;
- for(int i=1;i<=h;i++){
- for(int j=1;j<=w;j++){
- cin>>a[i][j];
- }
- }
- for(int i=1;i<=h;i++){
- for(int j=1;j<=w;j++){
- if(a[i][j]==0) cout<<'.';
- else{
- printf("%c",'A'+a[i][j]-1);
- }
- }
- cout<
- }
- return 0;
- }
大致题意就是对于A的每一个数,输出它们在所有数中(A和B的所有数)是第几小的数,对于B的每一个数,输出它们在所有数中是第几小的数
可以用两个指针分别遍历A和B中的每个数,然后两两比较,小的那个数就可以给它标记是第几小的数,双指针要注意边界问题,之前也做过类似的题目,经常搞不清边界,在这时就可以
用样例来试,发现如果A或B一边全部标记完了,那么剩下的就需要全部依次标记,可以将a[n+1]和b[m+1]初始化为超级大的数,这样的话,一边全部标记好之后,就可以把剩下的数依次标记了
注意while(l<=n||r<=m)用或而不是且
AC代码:
- #include
- #include
- #include
- #include
- using namespace std;
- const int N=1e5+10;
- int a[N],b[N];
- int idxa[N],idxb[N];
- int main()
- {
- int n,m;
- cin>>n>>m;
- for(int i=1;i<=n;i++) cin>>a[i];
- a[n+1]=1e9+10;
- for(int i=1;i<=m;i++) cin>>b[i];
- b[m+1]=1e9+10;
- int l=1,r=1;
- int idx=1;
- while(l<=n||r<=m){
- if(a[l]
- idxa[l]=idx;
- l++;
- idx++;
- }
- else if(a[l]>b[r]){
- idxb[r]=idx;
- r++;
- idx++;
- }
- }
- for(int i=1;i<=n;i++) cout<
" "; - cout<
- for(int i=1;i<=m;i++) cout<
" "; - cout<
- return 0;
- }

超时代码:
- #include
- #include
- #include
- #include
- #include
- using namespace std;
- const int N=5e5+10;
- bool flag[N];//表示是否被呼叫过
- set<int>s;
- int main()
- {
- int n,q;
- cin>>n>>q;
- for(int i=1;i<=n;i++) s.insert(i);
- while(q--){
- int op;
- cin>>op;
- if(op==1){
- for(auto v:s){
- if(!flag[v]){
- flag[v]=true;
- break;
- }
- }
- }
- else if(op==2){
- int x;
- cin>>x;
- s.erase(x);
- }
- else{
- for(auto v:s){
- if(flag){
- cout<
- break;
- }
- }
- }
- }
- return 0;
- }
实际上根本没必要用flag标记是否被呼叫过,如果是第一次被呼叫,那么直接将其放入set中,set中的就表示被呼叫过但没来的人,如果呼叫过然后来了的人就从set中删去
AC代码:
- #include
- #include
- #include
- #include
- #include
- using namespace std;
- set<int>s;
- int main()
- {
- int n,q;
- cin>>n>>q;
- int idx=1;
- while(q--){
- int op;
- cin>>op;
- if(op==1){
- s.insert(idx);//表示被呼叫过但没来
- idx++;
- }
- else if(op==2){
- int x;
- cin>>x;
- s.erase(x);//被呼叫过然后来了的
- }
- else{
- cout<<*s.begin()<
- }
- }
- return 0;
- }
大致题意是有一个行为2列为L的矩阵
这样输入:输入N1对数字(x,y),表示数字x有y个,依次填入第一行
同理,输入N2对数字(x,y),表示数字x有y个,依次填入第二行
最终,同一列的两个数字相等算一组,问一共有几组
首先,不能一个一个的填,因为L可以达到1e12,一个一个的填必定超时,共有N1+N2对,可以一对一对填,这样不会超时
然后填完之后,可以利用双指针进行判断,同时枚举上一边和下一边


代码如下:
- #include
- #include
- #include
- #include
- #include
- #include
- #define int long long
- using namespace std;
- vector
int,int>>a,b; - signed main()
- {
- int len,n1,n2;
- cin>>len>>n1>>n2;
- for(int i=1;i<=n1;i++){
- int x,y;
- cin>>x>>y;
- a.push_back({x,y});
- }
- for(int i=1;i<=n2;i++){
- int x,y;
- cin>>x>>y;
- b.push_back({x,y});
- }
- int l=0,r=0;
- int len1=a[0].second,len2=b[0].second;
- int res=0;
- if(a[0].first==b[0].first) res+=min(len1,len2);
- while(len1<=len||len2<=len){
- if(len1<=len2){
- l++;
- if(a[l].first==b[r].first) res+=min(a[l].second,len2-len1);
- len1+=a[l].second;
- }
- else{
- r++;
- if(b[r].first==a[l].first) res+=min(b[r].second,len1-len2);
- len2+=b[r].second;
- }
- }
- cout<
- return 0;
- }
进行改进:加上
if(len1==len&&len2==len) break;//如果双指针用while加if和else的话,最后不要忘记再加一句以退出循环
这样就没有RE了,此时还有点小错误,看来大方向是没问题的,只不过有一些小细节没有处理好,可能有特殊情况没有考虑到

代码如下:
- #include
- #include
- #include
- #include
- #include
- #include
- #define int long long
- using namespace std;
- vector
int,int>>a,b; - signed main()
- {
- int len,n1,n2;
- cin>>len>>n1>>n2;
- for(int i=1;i<=n1;i++){
- int x,y;
- cin>>x>>y;
- a.push_back({x,y});
- }
- for(int i=1;i<=n2;i++){
- int x,y;
- cin>>x>>y;
- b.push_back({x,y});
- }
- int l=0,r=0;
- int len1=a[0].second,len2=b[0].second;
- int res=0;
- if(a[0].first==b[0].first) res+=min(len1,len2);
- while(len1<=len||len2<=len){
- if(len1<=len2){
- l++;
- if(a[l].first==b[r].first) res+=min(a[l].second,len2-len1);
- len1+=a[l].second;
- }
- else{
- r++;
- if(b[r].first==a[l].first) res+=min(b[r].second,len1-len2);
- len2+=b[r].second;
- }
- if(len1==len&&len2==len) break;
- }
- cout<
- return 0;
- }
再进行改进,依旧是对边界的改进,改完之后又对了一个测试点
- if(len1
- if(len2
代码如下:
- #include
- #include
- #include
- #include
- #include
- #include
- #define int long long
- using namespace std;
- vector
int,int>>a,b; - signed main()
- {
- int len,n1,n2;
- cin>>len>>n1>>n2;
- for(int i=1;i<=n1;i++){
- int x,y;
- cin>>x>>y;
- a.push_back({x,y});
- }
- for(int i=1;i<=n2;i++){
- int x,y;
- cin>>x>>y;
- b.push_back({x,y});
- }
- int l=0,r=0;
- int len1=a[0].second,len2=b[0].second;
- int res=0;
- if(a[0].first==b[0].first) res+=min(len1,len2);
- while(len1<=len||len2<=len){
- if(len1<=len2){
- if(len1
- if(a[l].first==b[r].first) res+=min(a[l].second,len2-len1);
- len1+=a[l].second;
- }
- else{
- if(len2
- if(b[r].first==a[l].first) res+=min(b[r].second,len1-len2);
- len2+=b[r].second;
- }
- if(len1==len&&len2==len) break;
- }
- cout<
- return 0;
- }
此时样例错了一个,而且是样例二,第一行为1e10个1,第二行也为1e10个1
试了一下,发现res一开始+=1e10,然后len1变成了2e10,导致没有退出循环,后面res又加了,真是个巧合,这边可以避免len1变成2e10,即将res+=和len1+=都放到if(len1
AC代码:
- #include
- #include
- #include
- #include
- #include
- #include
- #define int long long
- using namespace std;
- vector
int,int>>a,b; - signed main()
- {
- int len,n1,n2;
- cin>>len>>n1>>n2;
- for(int i=1;i<=n1;i++){
- int x,y;
- cin>>x>>y;
- a.push_back({x,y});
- }
- for(int i=1;i<=n2;i++){
- int x,y;
- cin>>x>>y;
- b.push_back({x,y});
- }
- int l=0,r=0;
- int len1=a[0].second,len2=b[0].second;
- int res=0;
- if(a[0].first==b[0].first) res+=min(len1,len2);
- while(len1<=len||len2<=len){
- if(len1<=len2){
- if(len1
- l++;
- if(a[l].first==b[r].first) res+=min(a[l].second,len2-len1);
- len1+=a[l].second;
- }
-
- }
- else{
- if(len2
- r++;
- if(b[r].first==a[l].first) res+=min(b[r].second,len1-len2);
- len2+=b[r].second;
- }
- }
- if(len1==len&&len2==len) break;
- }
- cout<
- return 0;
- }
或者将len1==len改为大于等于
AC代码:
- #include
- #include
- #include
- #include
- #include
- #include
- #define int long long
- using namespace std;
- vector
int,int>>a,b; - signed main()
- {
- int len,n1,n2;
- cin>>len>>n1>>n2;
- for(int i=1;i<=n1;i++){
- int x,y;
- cin>>x>>y;
- a.push_back({x,y});
- }
- for(int i=1;i<=n2;i++){
- int x,y;
- cin>>x>>y;
- b.push_back({x,y});
- }
- int l=0,r=0;
- int len1=a[0].second,len2=b[0].second;
- int res=0;
- if(a[0].first==b[0].first) res+=min(len1,len2);
- while(len1<=len||len2<=len){
- if(len1<=len2){
- if(len1
- if(a[l].first==b[r].first) res+=min(a[l].second,len2-len1);
- len1+=a[l].second;
- }
- else{
- if(len2
- if(b[r].first==a[l].first) res+=min(b[r].second,len1-len2);
- len2+=b[r].second;
- }
- if(len1>=len&&len2>=len) break;
- }
- cout<
- return 0;
- }
总的来说,一开始大致方向是对的,双指针主要难点在于处理边界问题
-
相关阅读:
【C++】unordered_map和unordered_set
vivado时序分析-2时序分析关键概念
MMKV(2)
前端面试题(14)|求职季面试题分享|答案
一个基于RedisTemplate静态工具类
(01)ORB-SLAM2源码无死角解析-(38) EPnP 源代码分析(1)→PnPsolver总体流程与思路
SQL Server详细使用教程(包含启动SQL server服务、建立数据库、建表的详细操作) 非常适合初学者
Linux常用命令——clock命令
论文阅读《Robust Monocular Depth Estimation under Challenging Conditions》
单行函数,聚合函数课后练习
-
原文地址:https://blog.csdn.net/m0_74087709/article/details/131142517