策略游戏

题目链接

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;
}
posted @ 2022-11-21 23:06  TFLSNOI  阅读(27)  评论(0编辑  收藏  举报