策略游戏
题目链接
CSP2022-S-T2
题解1
纯模拟 60
#include<bits/stdc++.h>
using namespace std;
const int max_n=1e4+10, max_m=1e4+10;
int n, m, q;
long long a[max_n], b[max_m], c[max_n][max_m];
int l1, r1, l2, r2;
long long ans;
int main()
{
cin>>n>>m>>q;
for(int i=1; i<=n; i++)cin>>a[i];
for(int i=1; i<=m; i++)cin>>b[i];
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
c[i][j]=a[i]*b[j];
//cout<<c[i][j]<<" ";
}
//cout<<endl;
}
while(q--){
cin>>l1>>r1>>l2>>r2;
long long max_i=-(0x7fffffffffffffff);
int x, y;
for(int i=l1; i<=r1; i++){
long long min_j=(0x7fffffffffffffff), j2=l2;
for(int j=l2; j<=r2; j++)//求每一行的最小值
if(c[i][j]<min_j){
min_j=c[i][j];
j2=j;
}
if(min_j>max_i){//求所有行的最小值的最大值即为答案
max_i=min_j;
y=j2;
x=i;
}
}
cout<<c[x][y]<<endl;
}
return 0;
}
题解2
对题解1改进,根据矩阵的定义无需使用二维数组存放矩阵值,代码更短
#include<bits/stdc++.h>
using namespace std;
const int max_n=1e5+10, max_m=1e5+10;
int n, m, q;
long long a[max_n], b[max_m];
int l1, r1, l2, r2;
long long ans;
int main()
{
cin>>n>>m>>q;
for(int i=1; i<=n; i++)cin>>a[i];
for(int i=1; i<=m; i++)cin>>b[i];
while(q--){
cin>>l1>>r1>>l2>>r2;
long long max_i=-(0x7fffffffffffffff);
for(int i=l1; i<=r1; i++){
long long min_j=(0x7fffffffffffffff);
for(int j=l2; j<=r2; j++)//求每一行的最小值
if(b[j]*a[i]<min_j)//根据矩阵的定义矩阵值为b[j]*a[i];
min_j=b[j]*a[i];
if(min_j > max_i)//求所有行的最小值的最大值即为答案
max_i=min_j;
}
cout<<max_i<<endl;
}
return 0;
}
题解3
加入RMQ算法之后
居然还是60分
#include<bits/stdc++.h>
using namespace std;
const int max_n=1e5+100, max_m=1e5+100;
int n, m, q;
long long a[max_n], b[max_m];
int l1, r1, l2, r2;
int lg2[max_m];
int lg(){//对数函数底数为2, c++提供的log函数默认的底数是e ,此处功能相当于函数log2(),但速度要快
lg2[0]=-1;
for(int i=1; i<=max_m; i++){
lg2[i]=lg2[i/2]+1;
//cout<<i<<"-"<<lg2[i]<<" ";//测试使用
}
}
int fd[max_m][32];//区间最大值表
int fx[max_m][32];//区间最小值表
void st_table(int nn){
for(int i=1; i<=nn; i++)fd[i][0]=fx[i][0]=b[i];//ST初始化
int k=lg2[nn];
for(int j=1; j<=k; j++){
for(int i=1; i<=nn-(1<<j)+1; i++){
fx[i][j]=min(fx[i][j-1], fx[i+(1<<(j-1))][j-1]);
fd[i][j]=max(fd[i][j-1], fd[i+(1<<(j-1))][j-1]);
}
}
}
int st_query(int a, int l, int r){//ST表的查询
int k=lg2[r-l+1];
if(a>=0)
return min(fx[l][k], fx[r-(1<<k)+1][k]);
else
return max(fd[l][k], fd[r-(1<<k)+1][k]);
}
int main()
{
lg();
cin>>n>>m>>q;
for(int i=1; i<=n; i++)cin>>a[i];
for(int i=1; i<=m; i++)cin>>b[i];
st_table(m);//创建ST表
while(q--){
cin>>l1>>r1>>l2>>r2;
long long max_i=-(0x7fffffffffffffff);
for(int i=l1; i<=r1; i++){
long long min_j=a[i]*st_query(a[i], l2, r2);//求区间[l2, r2]之间的最小值,参数a[i]用于判断符号
if(min_j > max_i)//求所有行的最小值的最大值即为答案
max_i=min_j;
}
cout<<max_i<<endl;
}
return 0;
}