目录
A. Short Sort
Solution:按题意模拟即可。
#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
string s;cin>>s;
if(s=="abc"){
cout<<"Yes"<<'\n';
return;
}
for(int i=0;i<3;i++){
for(int j=i+1;j<3;j++){
string t=s;
swap(t[j],t[i]);
if(t=="abc"){
cout<<"Yes"<<'\n';
return;
}
}
}
cout<<"No"<<'\n';
}
int main()
{
int t;cin>>t;
while(t--) solve();
}
B. Good Kid
Solution:按题意模拟即可。
#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
int n;cin>>n;
vector<LL>a(n);
LL sum=1;
for(int i=0;i<n;i++) {cin>>a[i];sum*=a[i];}
LL mx=-inf;
for(int i=0;i<n;i++){
if(a[i]!=0)
mx=max(sum/a[i]+sum,mx);
else {
sum=1;
a[i]++;
for(int j=0;j<n;j++){
sum*=a[j];
}
cout<<sum<<'\n';
return;
}
}
cout<<mx<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
C. Target Practice
Solution:按题意模拟即可。
#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
char mp[11][11];
for(int i=1;i<=10;i++){
for(int j =1;j<=10;j++){
cin>>mp[i][j];
}
}
int mp1[11][11];
for(int i=1;i<=5;i++){
for(int j=i;j<=10-i+1;j++){
mp1[i][j]=mp1[j][i]=i;
}
}
int st=5;
for(int i=6;i<=10;i++){
for(int j=st;j<=10-st+1;j++){
mp1[i][j]=mp1[j][i]=st;
}
st--;
}
int sum=0;
for(int i=1;i<=10;i++){
for(int j=1;j<=10;j++){
if(mp[i][j]=='X') sum+=mp1[i][j];
}
}
cout<<sum<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
D. 1D Eraser
Solution:按题意模拟即可。
#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
int n,k;cin>>n>>k;
string s;cin>>s;
vector<int>pos;
for(int i=0;i<n;i++){
if(s[i]=='B') pos.push_back(i);
}
int len=pos.size();
int cnt=0;
for(int i=0;i<len;i++){
int j=i;
while(pos[j]<pos[i]+k&&j<len) j++;
cnt++;
i=j-1;
}
cout<<cnt<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
E. Building an Aquarium
Solution:二分,题意是找到一个最大值使得数组每一位等于这个值,并且所有比这个数小的数和这个值的差的和不超过给定的最大值k,注意右边界可以到2e9,赛时右边界开小了wa一发。
#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
vector<LL>ans(N);
int n,x;
bool chk(LL c){
LL sum=0;
for(int i=0;i<n;i++){
if(ans[i]<c) sum+=c-ans[i];
}
return sum<=x;
}
void solve()
{
cin>>n>>x;
LL mx=-inf;
for(int i=0;i<n;i++) {
cin>>ans[i];
mx=max(mx,ans[i]);
}
LL l=1,r=2e9+10;
LL an=-inf;
while(l<r){
LL mid=(l+r+1)>>1;
if(chk(mid)) {
l=mid;
}
else r=mid-1;
}
cout<<l<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
F. Money Trees
Solution:二分+贪心+前缀和。这题颇有感触,比完赛看了很少二分做法大部分都是双指针,以为自己写了假做法(bushi。题意是找到最长的连续序列,该序列满足相邻两项前一项可以整除后一项,区间的和不能超过给定值k。明显此题可以二分长度。二分答案前预处理不满足整除关系的点并且求前缀和,二分check的时候如果该长度的最小值小于k则此长度值可行。
#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
vector<LL>a(N+1),h(N+1),s(N+1);
vector<int>pos(N);
LL n,k;
bool chk(int x){
int len=pos.size();
LL mx=inf;
for(int i=1;i<=n;i++){
int po=lower_bound(pos.begin(),pos.end(),i)-pos.begin();
if(po==len){
if(i+x-1<=n) mx=min(mx,s[i+x-1]-s[i-1]);
}else{
if(i+x-1<=pos[po]){
mx=min(mx,s[i+x-1]-s[i-1]);
}
}
}
// cout<<mx<<'\n';
if(mx<=k) return 1;
else return 0;
}
void solve()
{
cin>>n>>k;
for(int i=1;i<=n;i++) {
cin>>a[i];
s[i]=0;
s[i]+=s[i-1]+a[i];
}
for(int i=1;i<=n;i++) cin>>h[i];
int st=0;
for(int i=1;i<n;i++){
if(h[i]%h[i+1]!=0){
pos[st++]=i;
}
}
//for(auto t:pos) cout<<t<<" ";
LL l=0,r=n,mx=-inf;
while(l<r){
LL mid=(l+r+1)>>1;
if(chk(mid)){
l=mid;
}else{
r=mid-1;
}
}
cout<<l<<'\n';
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--) solve();
}
G. ABBC or BACB
Solution:题意为对于只包含AB的字符串每次 可以将“AB”替换成“BC”,“BA”替换成“CB”。最多可以替换多少次,不难发现最大值与连续A的个数有关,因为可以连续替换,并且只能选择一个B的其中一边,另一边无法替换。因此分类讨论,当结尾是B时,则最大值是所有A的个数,否则,就将所有A的个数减去最少连续A的个数即可。
#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
void solve()
{
string s; cin>>s;
bool ok=true;
bool same=false;
int st=0;
vector<int> v;
for(int i=1;i<s.size();i++){
if(s[i]!=s[i-1]) ok=false;
if(s[i]==s[i-1]&&s[i]=='B') same=true;
}
for(int i=0;i<s.size();i++){
if(s[i]=='A') st++;
else{
if(st)
v.push_back(st);
st=0;
}
}
if(st) v.push_back(st);//分段的连续A的数量
if(ok) cout<<0<<'\n';
else
{
int res=count(s.begin(),s.end(),'A');
sort(v.begin(),v.end());
if(s.back()=='B'){
cout<<res<<'\n';
return;
}
if(!same&&s[0]=='A') res-=v[0];
cout<<res<<'\n';
}
}
int main()
{
int t;cin>>t;
while(t--) solve();
}
H. Mad City
Solution:dfs找环+bfs找交点。很有意思的一题,题意是给定一个互相连通的图,图上两点a,b,a追b问能否找到一个方案使得b永远不会被a抓到。因为n个点n条边,因此一定会有一个环,因此我们只要让b跑到最近的环,把距离记录下来,同时a也往b离环最近的位置跑,如果a离这个位置比b近或者相等,那么就不会存在方案。否则被永远不会被抓。因为可以连续替换
#include<iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include<stack>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
const int mod = 998244353;
const int N = 2e5+10;
const int inf = 0x3f3f3f3f;
LL gcd(LL a, LL b)
{
return b ? gcd(b, a % b) : a;
}
int lowbit(int x) {return x&-x;}
vector<int>v[N],dis(N);
vector<bool>vis(N),cir(N);
int n,a,b;
vector<int>path;
void dfs(int u,int fa){
vis[u]=true;
path.push_back(u);
for(auto t:v[u]){
if(t==fa) continue;
if(vis[t]){
for(int i=path.size()-1;i>=0;i--){
cir[path[i]]=true;
if(path[i]==t) break;
}
}else{
dfs(t,u);
}
}
vis[u]=false;
path.pop_back();
}
void solve()
{
cin>>n>>a>>b;
for(int i=1;i<=n;i++) v[i].clear(),cir[i]=false;
int x,y;
for(int i=0;i<n;i++){//n个点n条边只存在一个环
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
if(a==b) {
cout<<"No"<<'\n';
return;
}
dfs(1,-1);
for(int i=1;i<=n;i++) dis[i]=inf;
dis[b]=0;
queue<int>q;
q.push(b);
while(!q.empty()){
auto t=q.front();
q.pop();
for(auto t1:v[t]){
if(dis[t1]>dis[t]+1){
dis[t1]=dis[t]+1;
q.push(t1);
}
}
}
dis[0]=inf;
int id=0;
for(int i=1;i<=n;i++){
if(cir[i]&&dis[i]<dis[id]) id=i;
}
int ans=dis[id];//b 到环处的最短距离
q.push(a);
for(int i=1;i<=n;i++) dis[i]=inf;
dis[a]=0;
while(!q.empty()){
auto t=q.front();
q.pop();
for(auto t1:v[t]){
if(dis[t1]>dis[t]+1){
dis[t1]=dis[t]+1;
q.push(t1);
}
}
}
if(dis[id]<=ans){
cout<<"No"<<'\n';
}else cout<<"Yes"<<'\n';
}
int main()
{
int t;cin>>t;
while(t--) solve();
}