百度松果:oj第二周 使用ChatGPT写算法题

1.矩形

请用C++写代码:给定一个n*m的矩阵,1表示已经占用了,0表示没有被占用,请找出最大的由0构成的矩阵,输出其长和宽。

#include
using namespace std;
const int N=1005;
int a[N][N],sum[N][N],width[N],s[N];
int n,m;
bool Area(int x,int y,int c,int d)	//判断该矩阵是否全部由0组成
{
    for(int i=x;i<=c;i++)
    {
        for(int j=y;j<=d;j++)
        {
            if(a[i][j]==1) return 0;
        }
    }
    return 1;
}
int main(){
    cin>>n>>m;
    char c;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>c;
            a[i][j]=c-'0';
        }
    }
    int ans=0;//记录最大矩形周长
    
    for(int i=1;i<=n;i++){  //求每一块矩形
        for(int j=1;j<=m;j++){
            if(a[i][j]==1) continue;
            for(int p=i;p<=n;p++)
            {
                if(a[p][j]==1) break;
                for(int q=j;q<=m;q++)
                {
                    if(a[i][q]==1) break;
                    if(Area(i,j,p,q))
                    {
                        ans=max(ans,2*(p-i+1+q-j+1));	//更新最大周长
                    }
                }
            }
        }
    }

    
    cout<<ans<<endl;//输出最大矩形周长
    return 0;
}

2.切蛋糕

请用C++写代码:请用单调队列解决:有一块蛋糕分成了n个相同的部分,每一部分上面的水果都不同。由于小码哥对水果很有研究,他给每个水果都打了分。小码哥希望能吃到最多分数,但他又最多只能吃m块(m≤n)。请你帮他从这n小块中找出连续的最多m块蛋糕,使得其上的总分数最大。输入第一行两个整数n,m,意思如题目介绍;第二行n个整数,第i个整数代表第i部分的分数。输出一行一个整数,即小码哥能够得到的最大分数。

#include
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    int a[n+1];//数组注意开到n+1,否则会出错
    long long s[n+1],ans;
    s[0]=0;//前缀和初始化
    for(int i=1;i<=n;i++){//输入并求前缀和
        cin>>a[i];
        s[i]=s[i-1]+a[i];
    }
    deque<int> q;//定义双端队列
    ans=s[m];//初始化为前m个的和
    for(int i=0;i<m;i++)
    {
        if(ans<a[i]) ans=a[i];
        for(int j=i;j>=max(0,i-m);j--)
        {
            if(j){
                ans=max(ans,s[i]-s[j-1]);
            }
        }
    }
    q.push_back(m);//将右端点m先加入队列中
    for(int i=m+1;i<=n;i++){//枚举右端点
    while(!q.empty() && q.front()<i-m+1){//如果队头的下标k不在窗口内,说明k已经不可能是窗口内的最大值了,因此将其弹出队头。
        q.pop_front();
    }
    int j=q.front();//队头就是当前窗口内的最大值
        ans=max(ans,s[i]-s[j]);//更新答案
    while(!q.empty() && s[i]<s[q.back()]){//将新加入的i与队列中的数比较,如果比其小,则将其弹出,保证队列是递减的
    q.pop_back();
    }
    q.push_back(i);//将新的右端点加入队列中
    }
    cout<<ans<<endl;//输出
    return 0;
}

3.palace

请用C++写代码:给定一个n*m的矩阵,每个格子里有一个数,请找到一个最大区域,该区域内所有格子总和>0,并输出该区域面积。

#include 
using namespace std;
const int N = 1010;
int n, m, a[N][N], sum[N][N],ans;
int main(){
    cin >>n >> m;
    for (int i = 1; i <=n; i++) { //求出前缀和
        for (int j = 1;j <=m;j++)   {
            cin >> a[i][j];
            sum[i][j] = sum[i - 1][j] + sum[i][j - 1] +a[i][j] - sum[i - 1][j - 1];
        }
    }
    for (int i= 1; i <=n; i++)
        for (int j = 1;j <=m; j++)
            for (int k= i;k<= n; k++)
                for (int l=j; l<= m; l++) {
                    int tmp = (k - i +1)*(l-j +1);	//获得当前的面积
                    int tmp2 = sum[k][l] - sum[i - 1][l] - sum[k][j -1]+ sum[i - 1][j- 1]; 	//求区域和是否大于0
                    if (tmp > ans && tmp2 >0)
                        ans = tmp;	//更新答案
                }
    cout << ans;
    return 0;
}

4.数据流的中位数

请用C++写代码:对于数据流问题,小码哥需要设计一个在线系统,这个系统不断的接受一些数据,并维护这些数据的一些信息。中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。请帮小码哥设计一个支持以下两种操作的系统:+k表示从数据流中添加一个整数k到系统中( 0

#include
using namespace std;

priority_queue<int> max_heap; // 大根堆
priority_queue<int, vector<int>, greater<int> > min_heap; // 小根堆
int n;
int main() 
{
    cin >> n;
    for (int i = 0; i < n; i++) {
        char op;
        cin >> op;
        if (op == '+') {
                int k;
                cin >> k;
                if (max_heap.empty() || k <= max_heap.top()) { // 插入大根堆
                    max_heap.push(k);
                    if (max_heap.size() > min_heap.size() + 1) { // 大根堆堆顶元素移到小根堆
                        min_heap.push(max_heap.top());
                        max_heap.pop();
                    }
                } else { // 插入小根堆
                    min_heap.push(k);
                    if (min_heap.size() > max_heap.size()) { // 小根堆堆顶元素移到大根堆
                        max_heap.push(min_heap.top());
                        min_heap.pop();
                        }
                    }
                } else { // 输出中位数
                    if (max_heap.size() == min_heap.size())  // 列表长度为偶数,还需取一次平均值
                        cout << (max_heap.top() + min_heap.top()) / 2.0 << endl;
                    else
                        cout << max_heap.top()<<endl;
                }
    }
    return 0;
}

5.数三角形

请用C++写代码:给出四个整数A,B,C,D ,其中1≤A≤B≤C≤D≤5*10^5。求三边长分别为x, y, z(x , y, z为整数)并且满足A≤x≤B≤y≤C≤z≤D的非退化三角形(三顶点不共线)的个数。

#include
using namespace std;
typedef long long LL;
int main() {
    LL A, B, C, D;
    cin >> A >> B >> C >> D;
    long long ans = 0;
    for (int i = A; i <= B; i++) {
        for(int j=C; j>= B; j--)
        {
            if(i+j <= C) break;	//不满足三角不等式
            else
            {
                ans+=min(D-C+1,i+j-C); //找到符合要求的三角形总数
            }
        }
    }
    cout << ans << endl;
    return 0;
}

你可能感兴趣的:(牛客刷题,算法,数据结构,c++)