比赛链接:ABC370
AT 上 400 分寄。
Problem A:
Code
#include <bits/stdc++.h>
using namespace std;
int main(){int L,R;cin>>L>>R;if(L==R)cout<<"Invalid"<<endl;else if(L==1)cout<<"YES"<<endl;elsecout<<"NO"<<endl;return 0;
}
Problem B:
思路
拿一个二维数组模拟即可。
Code
#include <bits/stdc++.h>
using namespace std;
int A[105][105];
int main(){int N;cin>>N;for(int i=1;i<=N;i++){for(int j=1;j<=i;j++)cin>>A[i][j];}int ans=A[1][1];for(int i=2;i<=N;i++){if(ans>=i)ans=A[ans][i];elseans=A[i][ans];}cout<<ans<<endl;
}
Problem C:
思路
算是一道模拟。表示第 i 位有没有处理好;数组存需要处理的下标;用来记录位置和对应的字符串。我语文不大好,不会解释,看到代码你就懂了。
Code
#include <bits/stdc++.h>
using namespace std;
int mark[105];
int main(){string S,T;cin>>S>>T;vector<pair<string,int>> v;vector<int> pos;for(int i=0;i<S.size();i++){if(S[i]!=T[i]){pos.push_back(i);mark[i]=1;}}int cnt=pos.size();cout<<pos.size()<<endl;while(S!=T){for(int i=0;i<pos.size();i++){if(!mark[pos[i]])break;string tmp=S;tmp[pos[i]]=T[pos[i]];v.push_back(make_pair(tmp,pos[i]));}sort(v.begin(),v.end());cout<<v[0].first<<endl;S=v[0].first;mark[v[0].second]=0;v.clear();}return 0;
}
Problem D:
思路
维护和表示第 i 行剩余的列的集合以及第 j 列剩余的行的集合。
先判断是否位置上有墙,有的话直接删除掉。记得同时更新 row 和 col。
如果没有就在集合内二分,使用提供的 upper_bound
函数找到第一个比自己大的位置。之后往前走一个就可以得到比自己小的位置。
每一次尝试删除元素都要判断迭代器是否合法。
最后把所有内的元素个数加起来就是答案。
Code
#include <bits/stdc++.h>
using namespace std;
const int maxn=400005;
set<int> row[maxn],col[maxn];
void del(int r,int c){row[r].erase(c);col[c].erase(r);
}
int main(){int H,W,Q;cin>>H>>W>>Q;for(int i=1;i<=H;i++){for(int j=1;j<=W;j++){row[i].insert(j);col[j].insert(i);}}while(Q--){int r,c;cin>>r>>c;if(row[r].count(c)){del(r,c);continue;}if(!row[r].empty()){auto itr=row[r].upper_bound(c);if(itr!=row[r].end())del(r,*itr);if(!row[r].empty()){itr=row[r].upper_bound(c);if(itr!=row[r].begin()){itr--;del(r,*itr);}}}if(!col[c].empty()){auto itr=col[c].upper_bound(r);if(itr!=col[c].end())del(*itr,c);if(!col[c].empty()){itr=col[c].upper_bound(r);if(itr!=col[c].begin()){itr--;del(*itr,c);}}}}int ans;for(int i=1;i<=H;i++)ans+=row[i].size();cout<<ans<<endl;return 0;
}