牛客小白月赛95 (个人题解)(待完成)
前言:
昨天晚上写的小白月赛,以后估计会经常打这类竞赛,也给他写成博客发表出来吧,其中有几题不会写,照样还是以后在补吧(越积越多了)。
正文:
比赛链接:牛客小白月赛95_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com)
A 相遇
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b;
cin>>a>>b;
if(a==1&&b==2)cout<<"a";
if(a==1&&b==3)cout<<"b";
if(a==1&&b==1)cout<<"p";
if(a==2&&b==1)cout<<"b";
if(a==2&&b==2)cout<<"p";
if(a==2&&b==3)cout<<"a";
if(a==3&&b==2)cout<<"b";
if(a==3&&b==1)cout<<"a";
if(a==3&&b==3)cout<<"p";
return 0;
}
简单模拟。
B 宝石
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b;
cin>>a>>b;
if(b>2*a)cout<<11*a;
else cout<<a+5*b;
return 0;
}
两种情况分类讨论。
C 相助
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int b[N];
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> b[i];
}
if (n == 1) {
cout << -1;
return 0;
}
if (b[1] == b[n]) {
cout << 1;
return 0;
} else {
bool flag = 0;
for (int j = 2; j <= n - 2; j++) {
if (b[j] == b[1] && b[j + 1] == b[n]) {
flag = 1;
break;
}
}
if (flag == 1)
cout << 2;
else
cout << -1;
}
}
因为数组内只有0和1,所以答案只会有-1,1,2三种情况,很简单就能得出答案。
D 异或炸弹(easy)
#include<bits/stdc++.h>
using namespace std;
int a[3005][3005];
int main(){
int n,m,ans=0;
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y,r;
cin>>x>>y>>r;
int n1=r,n2=r-1;
for(int i=x;i>=1&&i>=x-r;i--){
int l1=max(1,y-n1),r1=min(n+1,y+n1+1);
a[i][l1]+=1;
a[i][r1]-=1;
n1--;
}
for(int i=x+1;i<=n&&i<=x+r;i++){
int l1=max(1,y-n2),r1=min(n+1,y+n2+1);
a[i][l1]+=1;
a[i][r1]-=1;
n2--;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n-1;j++){
a[i][j+1]+=a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]%2!=0)ans++;
}
}
cout<<ans;
return 0;
}
暴力的话会超时,我们对于每一行分别进行差分来优化就可以。
E 相依(待补,dp?)
待补。
F 异或炸弹(hard)
#include <bits/stdc++.h>
using namespace std;
const int N=6e3+10;
int n,m;
int s[N][N];
int main(){
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=0;i<m;i++){
int x,y,r;
cin>>x>>y>>r;
int nx=x+y,ny=x-y+3000;
int x1 = max(1,nx-r),y1=max(1,ny-r);
int x2 = min(6000,nx+r),y2=min(6000,ny+r);
s[x1][y1]++,s[x1][y2+1]--,s[x2+1][y1]--,s[x2+1][y2+1]++;
}
int res = 0;
for(int i=1;i<=6000;i++)
for(int j=1;j<=6000;j++){
s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
if((i&1)!=(j&1))continue;
int x=(i+j-3000)/2,y=(i-j+3000)/2;
if(x>=1&&x<=n&&y>=1&&y<=n&&s[i][j]&1)res++;
}
cout << res;
return 0;
}
看了题解才会做,其实思路比赛时我的队友已经想到了,但奈何我们知识储备还是太少了,并没有写出来。
思路: 旋转变换
核心:
曼哈顿距离转化为切比雪夫距离曼哈顿距离转化为切比雪夫距离
然后换成二维差分做就行了。
G 回文串(待补)
待补。
后记:
希望自己能越变越强吧,目前还是太弱了。