比赛链接
A.可以发现,只有abc至少有一个字母在其应在的位置上就可以输出YeS,否则输出NO
void solve(){
string s;
cin >> s;
int cnt = 0;
if(s[0]=='a') cnt++;
if(s[1]=='b') cnt++;
if(s[2]=='c') cnt++;
if(cnt==0){
cout<<"NO\n";
}else cout<<"YES\n";
}
B.乘积最大是让最小的数加一,先排序,把最小的数加一后乘起来就是答案。
#define ll long long
void solve(){
int n;
cin >> n;
vector<ll>a(n);
ll mi = 100000000;
for(int i = 0;i<n;i++){
cin >> a[i];
}
sort(a.begin(),a.end());
ll ma = a[0] + 1;
// int f = 0;
for(int i = 1;i<n;i++){
ma*=a[i];
}
cout<<ma<<endl;
}
C.可以把正方形看作由外到内的层级,比如(1,9)若横坐标或者纵坐标超过了5,就将其变为10-坐标+1,(6变成5 ,可以看图) (1,9)就成了(1,2)横纵坐标小的是它的层级。这样便利这个矩阵,找到所有x的层级,累加起来就是答案。
#define ll long long
void solve(){
char c[20][20];
int ans = 0;
for(int i = 1;i<=10;i++){
for(int j = 1;j<=10;j++){
cin >> c[i][j];
if(c[i][j]=='X'){
int ai = i;
int aj = j;
if(aj>5){
aj = 10 - aj + 1;
}
if(ai>5){
ai = 10 - ai + 1;
}
ans += min(ai,aj);
}
}
}
cout<<ans<<endl;
}
D.可以使用贪心策略:一旦便利到一个B,就立刻将其及右侧的K个都变为白色。
void solve(){
int n,k;
cin >> n >> k;
string s;
cin >> s;
int nx = -1;
int ans = 0;
for(int i = 0;i<n;i++){
if(s[i]=='B'&&i>=nx){
nx = i + k;
ans++;
}
}
cout<<ans<<endl;
}
E.可以放弃线性做法,直接二分答案(墙的长度)复杂度为 O(n*log(x)) ,在二分答案时,如果遍历到当前的数小于mid,累加mid - a[i],如果和大于 x(给的水不够填注),说明墙高了,向左,反之亦然。
#define ll long long
void solve(){
ll n,x;
cin >> n >> x;
vector<ll>a(n+1);
for(int i = 1;i<=n;i++){
cin >> a[i];
}
ll l = 1,r = 100000000000;
while(l<=r){
ll mid = (l+r)>>1;
ll sum = 0;
for(int i = 1;i<=n;i++){
sum += max(1ll*0,mid - a[i]);
}
if(sum > x){
r = mid - 1;
}else l = mid + 1;
}
cout<<r<<endl;
}
F.我的做法是先将所有合法的段全部存储,然后利用前缀和二分答案,二分时便利所有段。复杂度是 O(k*log(n)) (k为合法段的数量)
#define ll long long
void solve(){
int n,k;
cin >> n >> k;
vector<int>a(n+1);
vector<int>h(n+1);
vector<ll>s(n+1);//存储前缀和
for(int i = 1;i<=n;i++){
cin >> a[i];
s[i] = s[i-1] + a[i];
}
for(int i = 1;i<=n;i++){
cin >> h[i];
}
int cnt = 0;
vector<pair<int,int>> res;//存储合法段
int f = 0;
for(int i = 0;i<n;i++){
if(h[i]%h[i+1]==0){
cnt++;
}else{
// cout<<i<<' ';
res.push_back({i+1-cnt,i});
cnt = 1;
}
}
res.push_back({n-cnt+1,n});
int l = 0,r = n;
//二分答案
while(l<=r){
int mid = (l+r)>>1;
int f = 0;
for(auto q:res){
int x = q.first,y = q.second;
if(mid>(y-x+1)){
continue;
}
ll sum = 0;
for(int i = x,j = x+mid;j<=y;i++,j++){
if(s[j] - s[i-1]<=k){
f = 1;
}
}
}
if(f){
l = mid + 1;
} else r = mid - 1;
}
cout<<l<<'\n';
}