前言:
当天晚上小白有事没有打,赛后模拟了一下,A了三题,无Wa,E题绷了半天出不来,估计是能上分(应该?)
赛后补补题
花了点时间把D和E补完了(累~~) -----2024.9.10
1.ACM中的A题
直接枚举每条边乘2的结果判断即可
估计要开longlong ?? (要的)
LL san(LL a,LL b,LL c){
if(a+b<=c || a-b>=c || b+c<=a || b-c>=a || a+c<=b || a-c>=b){
return 0;
}
else{
return 1;
}
}
void solve()
{
LL a,b,c,a1,b1,c1;
cin>>a>>b>>c;
a1 = a ,b1 = b,c1 = c;
a1*=2;
if(san(a1,b1,c1)==1){
cout<<"Yes";
return;
}
a1 = a;
b1*=2;
if(san(a1,b1,c1)==1){
cout<<"Yes";
return;
}
b1 = b;
c1*=2;
if(san(a1,b1,c1)==1){
cout<<"Yes";
return;
}
cout<<"No";
}
2. ACM中的C题
特判一下n==1的情况,然后分奇数和偶数计算,奇数就要多花一次机会交换
void solve()
{
int n;
cin>>n;
vector<int> a(n);
for(int i=1;i<=n;i++) cin>>a[i];
if(n==1){
cout<<-1;
}
else{
if(n%2==0){
cout<<n/2;
}
else{
cout<<n/2+1;
}
}
}
3. ACM中的M题
同样道理,先特判n==1 ,然后对于同一类型若只有一个,也是不行的,考虑用Map存储计算答案
void solve()
{
int n;
cin>>n;
vector<int> a(n+1,0),b(n+1,0);
for(int i=1;i<=n;i++) cin>>a[i];
map<LL,LL> q;
for(int i=1;i<=n;i++){
cin>>b[i];
q[b[i]]++;
}
if(n==1){
cout<<-1;
}
else{
vector<int> dp;
for(auto &i:q){
if(i.second==1){
cout<<-1;
return;
}
else{
dp.push_back(i.second);
}
}
LL ans = 0;
for(int i = 0;i<dp.size();i++){
if(dp[i]%2==0){
ans+=(dp[i]/2);
}
else{
ans+=(dp[i]/2+1);
}
}
cout<<ans;
}
}
4. ACM中的AC题
思考点:选定一个点后,走入传送门结束,另一个点一定可以沿着刚刚的路径走回去(但不一定是最大,而且保证走之前没被堵死)
1.使用dis来存储先进的点,d来存储后进的点位
2.在dis中尽可能铺满所有可以走的点,判断另一个方向不会被堵死,实际操作就是一个点进完了后,另一个点 在对称点,再计算一次由附近最近的@点进行收容,一次向外括,一次向内
#include <bits/stdc++.h>
using namespace std;
using LL =long long;
const int N = 2e3+5;
int n,m,x,y;
int dis[N][N],d[N][N];
char a[N][N];
int dx[4] = {1,0,-1,0};
int dy[4] = {0,-1,0,1};
bool ckn(int x,int y){
return x>=1 && x<=n && y>=1 && y<=m && a[x][y]!='#';
}
void solve(){
cin>>n>>m>>x>>y;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
dis[i][j] = 1e9;
d[i][j] = 1e9;
}
}
queue<pair<int,int> > q;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]=='@'){
d[i][j] = 0;
q.push({i,j});
}
}
}
while(!q.empty()){
auto op = q.front();
int cx = op.first;
int cy = op.second;
q.pop();
for(int i=0;i<4;i++){
int nx = cx + dx[i];
int ny = cy + dy[i];
if(ckn(nx,ny) && d[nx][ny]>d[cx][cy]+1){
d[nx][ny] = d[cx][cy] + 1;
q.push({nx,ny});
}
}
}
dis[x][y]=0;
q.push({x,y});
while(!q.empty()){
auto op = q.front();
int cx = op.first;
int cy = op.second;
q.pop();
for(int i=0;i<4;i++){
int nx = cx + dx[i];
int ny = cy + dy[i];
if(ckn(nx,ny) && ckn(2*x-nx,2*y-ny) && dis[nx][ny]>dis[cx][cy]+1){
dis[nx][ny] = dis[cx][cy] + 1;
q.push({nx,ny});
}
}
}
int ans = 2e9;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]=='@'){
ans = min(ans , dis[i][j]+d[2*x-i][2*y-j]);
}
}
}
if(ans>=1e9){
cout<<-1;
}
else{
cout<<ans;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int t = 1;
while(t--){
solve();
}
}
5. ACM中的CM题
赛时考虑用二分答案,但是似乎答案单调性有问题???,一直分不出来,看了题解还是用暴力做吧。
可能考虑的过程错了,和题解计算二分的地方不一样,题解计算的是算给定的m值后需要的数来覆盖所有地雷,
直接二分m的值可能会有遗漏??
#include<bits/stdc++.h>
using namespace std;
using LL = long long ;
vector<int>a;
int check(int x) {
int ans = x;
int pos = a[1];
while (1) {
ans++;
pos = std::upper_bound(a.begin() + 1, a.end(), pos + x) - a.begin();
if (pos == a.end() - a.begin()) break;
pos = a[pos];
}
return ans;
}
int main()
{
int n;
cin>>n;
a.push_back(0);
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
a.push_back(x);
}
sort(a.begin()+1,a.end());
int ans = 1e6;
for(int i=0;i<n;i++)
{
ans=min(ans,check(i));
}
cout<<ans<<endl;
}