训练情况
赛后反思
D题差一点点吧?可能不去乐跑就能写出来了
A题
我们发现 ABC
是字典序单调递增的,字符串先排序再判断是否为 ABC
即可。
#include <bits/stdc++.h>
#define int long longusing namespace std;void solve(){string s; cin>>s;sort(s.begin(),s.end());if(s == "ABC") cout<<"Yes"<<endl;else cout<<"No"<<endl;
}signed main(){// int T; cin>>T; while(T--)solve();return 0;
}
B题
记录每一行每一列是否有棋子,有就不能放,最后每一格都枚举一遍,判断当前行当前列是否有棋子即可,没有棋子就答案加一。
#include <bits/stdc++.h>
#define int long longusing namespace std;void solve(){vector<string> s(8);for(int i = 0;i<8;i++) cin>>s[i]; vector<bool> r(8),c(8);int ans = 0;for(int i = 0;i<8;i++){for(int j = 0;j<8;j++){if(s[i][j] == '#') r[i] = 1,c[j] = 1;}}for(int i = 0;i<8;i++){for(int j = 0;j<8;j++){if(!r[i]&&!c[j]) ans++;}}cout<<ans<<endl;
}signed main(){// int T; cin>>T; while(T--)solve();return 0;
}
C题
上一题的加强版?这次可以往八个方向,考虑到可能会出现重复被占的点,所以我们用 set 进行去重即可,最后判断棋子是否在棋盘上,求被占的格子,最后再用全部的减一下即可。
#include <bits/stdc++.h>
#define int long longusing namespace std;void solve(){int n,m; cin>>n>>m;set<pair<int,int>> s;for(int i = 1;i<=m;i++){int x,y; cin>>x>>y;s.insert({x,y});s.insert({x+2,y+1});s.insert({x+1,y+2}); s.insert({x-1,y+2});s.insert({x-2,y+1});s.insert({x-2,y-1});s.insert({x-1,y-2});s.insert({x+1,y-2});s.insert({x+2,y-1});}int ans = 0;for(auto i:s){if(i.first>=1&&i.first<=n&&i.second>=1&&i.second<=n) ans++;}cout<<n*n-ans<<endl;
}signed main(){// int T; cin>>T; while(T--)solve();return 0;
}
D题
考虑 \(O(m)\) 的同时,维护一个左边界,就是当前位置能最多往前多少是刚好不完全覆盖的,最后这个左边界需要取个 max,因为如果前面的左边界更右,那后面的左边界也要和前面一样。
#include <bits/stdc++.h>
#define int long longusing namespace std;void solve(){int n,m; cin>>n>>m;vector<int> d(m + 1,1);for(int i = 1;i<=n;i++){int l,r; cin>>l>>r;d[r] = max(d[r],l+1);} for(int i = 1;i<=m;i++){d[i] = max(d[i],d[i-1]);}int ans = 0;for(int i = 1;i<=m;i++){ans += i - d[i] + 1;}cout<<ans<<endl;
}signed main(){// int T; cin>>T; while(T--)solve();return 0;
}