从入门到头秃周末休闲赛4

周末一位朋友喊我打了一场比赛 我觉得比较有意思 就把它记录一下把~
在这里插入图片描述

A - 高橋くんの集計 AtCoder - 1014

题目

高橋くんは、上司から

会社で作っている N 個のソフトウェアに平均でどれくらいのバグがあるか調べろ
ただし、バグがないソフトは調査母数に含めるな
と指示されました。

しかも、上司は小数が嫌いです。とはいえ、バグ数の平均値を過小報告するわけにもいかないので、値を切り上げて報告することにしました。

高橋くんは、素早くバグ数の平均値をまとめて上司に報告する必要があります。 ソフトウェアごとのバグ数が与えられるので、バグが含まれるソフトウェアの、バグ数の平均値を小数で切り上げて求めてください。

输入格式
入 力 は 以 下 の 形 式 で 標 準 入 力 か ら 与 え ら れ る 。 入力は以下の形式で標準入力から与えられる。

N
A 1 A 2 . . . A N A_1 A_2 ... A_N A1A2...AN
1 行目には、ソフトウェアの数を表す整数 N ( 1 ≦ N ≦ 100 ) N (1 ≦ N ≦ 100) N(1N100) がスペース区切りで与えられる。
2 行目では、それぞれのソフトウェアに含まれるバグの数の情報が、スペース区切りで与えられる。 i 番目のソフトウェアのバグの数は、 i 番目に与えられる整数 A i ( 0 ≦ A i ≦ 100 ) A_i (0 ≦ A_i ≦ 100) Ai(0Ai100)によって与えられる。
与えられるソフトウェアのバグの合計数は、 1 つ以上であることが保証されている。

输入格式

バグが含まれるソフトウェアの、バグ数の平均値を小数で切り上げて 1 行で出力せよ。出力の末尾には改行をいれること。

输入输出样例

#1

4
0 1 3 8

4

#2

5
1 4 9 10 15

8

解释(幸亏有这个)

听说你们很多人看不懂日语啊哈哈,那前面就不用看了,就是输入n个非负整数,对正数求平均值要向上取整

思路

注意一下如果数是0的话就不算它,最后算平均也不计。

代码

#include <cstdio>
using namespace std;
int main()
{
    int n,sum=0,cnt=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int x;
        scanf("%d",&x);
        if(x!=0)
        cnt++;
        sum+=x;
    }
    if(sum%cnt==0)
    printf("%d\n",sum/cnt);
    else
    printf("%d\n",sum/cnt+1);
}

B - 单词翻转 51 Nod - 2645

题目

输入一个句子(一行),将句子中的每一个单词翻转后输出。

输入格式

只有一行,为一个字符串(只包含小写字母),不超过1000个字符。单词之间用空格隔开。

输出格式

翻转每一个单词后的字符串,单词之间的空格需与原文一致。

输入样例
z wtg bqd dvhfi axpu u gpu

输出样例

z gtw dqb ifhvd upxa u upg

思路

用string 的getline输入进去,用stringstream把单词分开,最后用reverse把string倒过来 ,最后输出。

代码

#include <string>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1000+10;
string ans[maxn];
int main()
{
    int k=0;
    string s,t;
    getline(cin,s);
    stringstream s1;
    s1<<s;
    while(s1>>t)
    {
        ans[k++]=t;
    }
    for(int i=0;i<k;i++)
    reverse(ans[i].begin(),ans[i].end());
    for(int i=0;i<k;i++)
    cout<<ans[i]<<" ";
}

C - 连续和 NBUT - 1096

题目

任何一个正整数都能分解成a+(a+1)+(a+2)+…+b的连续正整数和的形式,我们想要找出项数最多的一种形式

输入格式
多组输入数据,每行输入一个N,且1 ≤ N ≤ 10^9

输出格式

对于每个输入,输出那个连续和形式里面最小的数,以及项数

输入样例
14
2

输出样例

2 4
2 1

思路

这题真的快把我气炸了 它题目里没写n=0的时候结束,导致我wa了12发都不知道哪里错了 最后终于对了。

用等差数列求k+1项到n项的公式 k m + k ∗ ( k + 1 ) = N km+k*(k+1)=N km+k(k+1)=N

推导过程如下:

在这里插入图片描述

在这里插入图片描述

之后只需要从最大的项往前找,找到第一个符合方程的就是最优解。

代码

#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long ll;
#define ll long long
// using namespace std;
int maxk = 60000+10;

int main()
{
    ll n;
    while(~scanf("%lld",&n)&&n)
    {
        for(ll i=maxk;i>=1;i--)
        {
            if(n*2-(i+1)*i<0) continue;
            if((n*2-(i+1)*i)%(2*i)==0)
            {
                // printf("%lld %lld %lld %lld \n",n,(n*2-(i+1)*i),(2*i),i);
                printf("%lld %lld\n",(n*2-(i+1)*i)/(2*i)+1,i);
                break;
            }
        }
    }
}

在这里插入图片描述
这题真是太坑了 没写输入到0结束(汗)

D - 所有可能的子集

题目

In a Lotto I have ever played, one has to select 6 numbers from the set {1,2,…,49}. A popular strategy to play Lotto - although it doesn’t increase your chance of winning - is to select a subset S containing k (k>6) of these 49 numbers, and then play several games with choosing numbers only from S. For example, for k=8 and S = {1,2,3,5,8,13,21,34} there are 28 possible games: [1,2,3,5,8,13], [1,2,3,5,8,21], [1,2,3,5,8,34], [1,2,3,5,13,21], … [3,5,8,13,21,34].

Your job is to write a program that reads in the number k and the set S and then prints all possible games choosing numbers only from S.
Input
The input file will contain one or more test cases. Each test case consists of one line containing several integers separated from each other by spaces. The first integer on the line will be the number k (6 < k < 13). Then k integers, specifying the set S, will follow in ascending order. Input will be terminated by a value of zero (0) for k.
Output
For each test case, print all possible games, each game on one line. The numbers of each game have to be sorted in ascending order and separated from each other by exactly one space. The games themselves have to be sorted lexicographically, that means sorted by the lowest number first, then by the second lowest and so on, as demonstrated in the sample output below. The test cases have to be separated from each other by exactly one blank line. Do not put a blank line after the last test case.

Sample Input
7 1 2 3 4 5 6 7
8 1 2 3 5 8 13 21 34
0
Sample Output

1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 6 7
1 2 3 5 6 7
1 2 4 5 6 7
1 3 4 5 6 7
2 3 4 5 6 7

1 2 3 5 8 13
1 2 3 5 8 21
1 2 3 5 8 34
1 2 3 5 13 21
1 2 3 5 13 34
1 2 3 5 21 34
1 2 3 8 13 21
1 2 3 8 13 34
1 2 3 8 21 34
1 2 3 13 21 34
1 2 5 8 13 21
1 2 5 8 13 34
1 2 5 8 21 34
1 2 5 13 21 34
1 2 8 13 21 34
1 3 5 8 13 21
1 3 5 8 13 34
1 3 5 8 21 34
1 3 5 13 21 34
1 3 8 13 21 34
1 5 8 13 21 34
2 3 5 8 13 21
2 3 5 8 13 34
2 3 5 8 21 34
2 3 5 13 21 34
2 3 8 13 21 34
2 5 8 13 21 34
3 5 8 13 21 34

题意

给你n个数,求能组成的6个数的递增序列的个数。

思路

全排列选数,选完以后判断是否是升序 是的话输出完事。

代码

#include <cstdio>
using namespace std;
const int maxn = 20;
int a[maxn],bk[maxn],ans[maxn],n;

void dfs(int now)
{
    if(now==7)
    {
        int flag=1;
        for(int i=2;i<=6;i++)
        {
            if(ans[i]<=ans[i-1])
            flag=0;
        }
        if(flag)
        {
            for(int i=1;i<=6;i++)
            {
                if(i!=6)
                printf("%d ",ans[i]);
                else
                printf("%d",ans[i]);
            }
            printf("\n");
        }
        return ;
    }
    else
    {
        for(int i=1;i<=n;i++)
        {
            if(!bk[i])
            {
                bk[i]=1;
                ans[now]=a[i];
                dfs(now+1);
                bk[i]=0;
                ans[now]=0;
            }
        }
    }
}
int main()
{
    int cnt=0;
    while(~scanf("%d",&n) && n)
    {
        if(cnt)
        printf("\n");
        cnt++;
        for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        dfs(1);
    }
}

坑点

这题的坑点是格式问题,只有最后一行没有回车对于这种多组输入的题来说非常致命,所以我们只让第一行不输出回车,其他行都输出回车即可。

E - 矩阵乘法

题目

给出2个N * N的矩阵M1和M2,输出2个矩阵相乘后的结果。
Input
第1行:1个数N,表示矩阵的大小(2 <= N <= 100) 第2 - N + 1行,每行N个数,对应M1的1行(0 <= M1i <= 1000) 第N + 2 - 2N + 1行,每行N个数,对应M2的1行(0 <= M2i <= 1000)
Output
输出共N行,每行N个数,对应M1 * M2的结果的一行。
Sample Input
2
1 0
0 1
0 1
1 0
Sample Output
0 1
1 0

思路

裸题一个 直接切了。

代码

#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100+10;
int n;
class node
{
    public:
        int a[maxn][maxn];
};

node Mul(node a,node b)
{
    node c;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    c.a[i][j]=0;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    for(int k=1;k<=n;k++)
    c.a[i][j]+=a.a[i][k]*b.a[k][j];
    return c;
}
int main()
{
    node a,b;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    scanf("%d",&a.a[i][j]);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    scanf("%d",&b.a[i][j]);
    node ans = Mul(a,b);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(j==n)
            printf("%d",ans.a[i][j]);
            else
            printf("%d ",ans.a[i][j]);
        }
        printf("\n");
    }
}

F - 铺地毯

题目

为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n张地毯,编号从 1 到n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。
地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。

在这里插入图片描述
Input
输入共 n+2行。
第一行,一个整数 n,表示总共有 n张地毯。
接下来的 n行中,第 i+1行表示编号 i的地毯的信息,包含四个正整数 a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标(a,b)以及地毯在 x轴和 y轴方向的长度。
第 n+2 行包含两个正整数 x 和 y,表示所求的地面的点的坐标(x,y) 。
Output
输出共 1 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出-1。
Sample Input
3
1 0 2 3
0 2 3 3
2 1 3 3
2 2
Sample Output
3
Hint
【输入输出样例说明】
如上图,1 号地毯用实线表示,2 号地毯用虚线表示,3 号用双实线表示,覆盖点(2,2)的最上面一张地毯是 3 号地毯。

思路

想要找到最上面的地毯,那么就直接倒着找,找到一个满足条件的输出就得了,如果找不到就输出-1。

代码

#include<stdio.h>
int main( )
{
    int n,i,x,y;
    scanf("%d",&n);
    int a[n+1][5];
    for(i=1;i<=n;i++)
    {
        scanf("%d%d%d%d",&a[i][1],&a[i][2],&a[i][3],&a[i][4]);//1 x0 2 y0 3 x1 4 y1
    }
    scanf("%d%d",&x,&y);
    int f=0;
    for(int i=n;i>=1;i--)
    {
        if(x>=a[i][1]&&x<=a[i][1]+a[i][3]&&y>=a[i][2]&&y<=a[i][2]+a[i][4])
        {
            f=1;
            printf("%d",i);
            break;
        }
    }
    if(!f)
    printf("-1");
    return 0;
}

G - 和为k的连续区间

一整数数列a1, a2, … , an(有正有负),以及另一个整数k,求一个区间i,j,(1 <= i <= j <= n),使得ai + … + aj = k。

Input
第1行:2个数N,K。N为数列的长度。K为需要求的和。(2 <= N <= 10000,-10^9 <= K <= 10^9) 第2 - N + 1行:Ai(-10^9 <= Ai <= 10^9)。
Output
如果没有这样的序列输出No Solution。 输出2个数i, j,分别是区间的起始和结束位置。如果存在多个,输出i最小的。如果i相等,输出j最小的。
Sample Input
6 10
1
2
3
4
5
6
Sample Output
1 4

思路

暴力过的…

代码

#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 10000+10;
ll a[maxn];

int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)
    {
        ll sum=0;
        for(int j=i;j<=n;j++)
        {
            sum+=a[j];
            if(sum==k)
            return printf("%d %d",i,j),0;
        }
    }
    printf("No Solution");
}

H - 棋盘

题目

有一个 m \times mm×m 的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。

任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的),你只能向上、下、左、右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同,那你不需要花费金币;如果不同,则你需要花费 11 个金币。

另外,你可以花费 22 个金币施展魔法让下一个无色格子暂时变为你指定的颜色。但这个魔法不能连续使用,而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法;只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。

现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?

输入格式
数据的第一行包含两个正整数 mm,nn,以一个空格分开,分别代表棋盘的大小,棋盘上有颜色的格子的数量。

接下来的 nn 行,每行三个正整数 xx ,yy,cc,分别表示坐标为(xx,yy)的格子有颜色 cc。其中 c=1c=1 代表黄色,c=0c=0 代表红色。相邻两个数之间用一个空格隔开。棋盘左上角的坐标为( 1,11,1 ),右下角的坐标为( m, mm,m )。

棋盘上其余的格子都是无色。保证棋盘的左上角,也就是(1,11,1)一定是有颜色的。

输出格式
输出一行,一个整数,表示花费的金币的最小值,如果无法到达,输出 -1−1 。

数据范围
对于 30%30% 的数据,1 \le m \le 51≤m≤5, 1 \le n \le 101≤n≤10。

对于 60%60% 的数据,1 \le m \le 201≤m≤20, 1 \le n \le 2001≤n≤200。

对于 100%100% 的数据,1 \le m \le 1001≤m≤100, 1 \le n \le 1,0001≤n≤1,000。

样例说明
样例1:
在这里插入图片描述

从(11,11)开始,走到(11,22)不花费金币从(11,22)向下走到(22,22)花费 11 枚金币从(22,22)施展魔法,将(22,33)变为黄色,花费 22 枚金币从(22,22)走到(22,33)不花费金币从(22,33)走到(33,33)不花费金币从(33,33)走到(33,44)花费 11 枚金币从(33,44)走到(44,44)花费 11 枚金币从(44,44)施展魔法,将(44,55)变为黄色,花费 22 枚金币,从(44,44)走到(44,55)不花费金币从(44,55)走到(55,55)花费 11 枚金币共花费 88 枚金币。

样例2:

在这里插入图片描述

从(1,1)走到(1,2),不花费金币从(1,2)走到(2,2),花费 1金币施展魔法将(2,3)变为黄色,并从(2,2)走到(2,3)花费 2金币从(2,3)走到(3,3)不花费金币

从(3,3)只能施展魔法到达(3,2),(2,3),(3,4),(4,3)

而从以上四点均无法到达(5,5),故无法到达终点,输出-1

输出时每行末尾的多余空格,不影响答案正确性

样例输入1
5 7
1 1 0
1 2 0
2 2 1
3 3 1
3 4 0
4 4 1
5 5 0
样例输出1
8
样例输入2
5 5
1 1 0
1 2 0
2 2 1
3 3 1
5 5 0
样例输出2
-1

题意

从一个棋盘的左上角走到右下角,每一步脚底都必须有颜色。如果两个地板的颜色相同,那么走过去就不话费金币,如果颜色不同的话,就花费1金币。每一步可以选择将无颜色的地板变成当前的颜色,但是需要花费2金币且不能连续使用,一直走到下一次有颜色的地方,这里会变成无色的,而又能把别的变成有颜色的地方了。求走到终点的最小化费是多少。

思路

dfs跑一遍。
1、如果下一步颜色不一样now就+1
2、如果下一步颜色一样now不变,走下一步
3、如果下一步没有颜色,那么把他变得有颜色,且和当前颜色一样(这样走过去就没有花费)。

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100+10;
int mp[maxn][maxn],ansmp[maxn][maxn],m,n,flag;

int dx[]={1,-1,0,0};
int dy[]={0,0,-1,1};

bool check(int x,int y)
{
    return x>=1 && y>=1 && x<=m && y<=m && mp[x][y];
}

int ans = 0xfffffff;

void dfs(int x,int y,int now,bool isok)
{
    if(now>=ansmp[x][y]) return;
    ansmp[x][y]=now;
    if(x==m && y==m)
    {
        flag=1;
        ans=min(ans,now);
        return ;
    }
    for(int i=0;i<4;i++)
    {
        int xx = x + dx[i];
        int yy = y + dy[i];
        if(check(xx,yy))
        {
            if(mp[x][y]==mp[xx][yy])
                dfs(xx,yy,now,false);
            else
                dfs(xx,yy,now+1,false);
        }
        else
        {
            if(!isok)
            {
                mp[xx][yy]=mp[x][y];//染色
                dfs(xx,yy,now+2,true);
                mp[xx][yy]=0;
            }
        }
    }
}
int main()
{
    for(int i=1;i<=100;i++)
    for(int j=1;j<=100;j++)
    ansmp[i][j]=0xfffffff;
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);//1 黄 0 红
        mp[x][y]=z+1;
    }
    dfs(1,1,0,false);
    if(flag)
    printf("%d\n",ans);
    else
    printf("-1\n");
}

I - 斜率小于0的连线数量

题目

二维平面上N个点之间共有C(n,2)条连线。求这C(n,2)条线中斜率小于0的线的数量。
二维平面上的一个点,根据对应的X Y坐标可以表示为(X,Y)。例如:(2,3) (3,4) (1,5) (4,6),其中(1,5)同(2,3)(3,4)的连线斜率 < 0,因此斜率小于0的连线数量为2。
Input
第1行:1个数N,N为点的数量(0 <= N <= 50000) 第2 - N + 1行:N个点的坐标,坐标为整数。(0 <= X, Y <= 10^9)
Output
输出斜率小于0的连线的数量。(2,3) (2,4)以及(2,3) (3,3)这2种情况不统计在内。
Sample Input
4
2 3
3 4
1 5
4 6
Sample Output
2

思路

由于这题要找斜率小于零的连线的个数,我们先对于x进行升序排列,如果两个x相同的话就让y按照升序排列,这样的话就不会产生逆序对了。剩下的情况我们只需要找逆序对的个数(x大于前面,但是y小,这样的话连线就是斜率小于零的了)。利用归并排序找逆序对的个数即可。

代码

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 500000+100;
class Point
{
    public:
        ll x,y;
}a[maxn];

int b[maxn],c[maxn];
long long ans;

bool cmp(Point a,Point b)
{
    return a.x==b.x?a.y<b.y:a.x<b.x;//如果x相同的话,y升序不会产生逆序对.
}

void merge_sort(int l,int r)
{
    int mid = l+r>>1;
    if(l==r) return;
    else
    {
        merge_sort(l,mid);
        merge_sort(mid+1,r);
    }
    int i = l;
    int j = mid+1;
    int k = l;//下标
    while(i<=mid && j<=r)
    {
        if(b[i]>b[j])
        {
            ans+=mid-i+1;
            c[k++]=b[j];
            j++;
        }
        else
        {
            c[k++]=b[i];
            i++;
        }
    }
    while(i<=mid)
    {
        c[k++]=b[i];
        i++;
    }
    while(j<=r)
    {
        c[k++]=b[j];
        j++;
    }
    for(int i=l;i<=r;i++)
    b[i]=c[i];
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%lld%lld",&a[i].x,&a[i].y);
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
    b[i]=a[i].y;
    merge_sort(1,n);
    printf("%lld\n",ans);
}

J - 学长的别墅

题目

话说L学长变成了土豪,他想找一块地建别墅,于是他找到了一块地,但这块地有些地方不能在上面建,于是在地图上标记为1,其它能用的地方都标记为0。他想找最大的一块矩形区域来建别墅,不过地太大了,手工计算实在是麻烦,你能帮帮他吗

Input
第一行,输入n和m,表示接下来有n行m列,n和m都是不大于1400的正整数,接下来的n行m列就是个01矩阵,含义如描述

Output
输出最大的一块矩形区域的面积

Sample Input
4 5
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0
0 0 0 1 0
Sample Output
6

思路

这题和那道在一堆高楼里找最大面积的题不同,是找矩阵里面的最大面积。
有了那道题的铺垫,我们可以这样:把每一行往上能扩展的最大数量先预处理出来,然后对于没一行走一遍单调栈求高楼最大面积的操作,最后求出来的最大值就是最大面积。

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define nn printf("\n")
const int maxn = 1400+20;
int mp[maxn][maxn];

class node
{
    public:
        int width;
        int height;
}st[maxn];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        int x;
        scanf("%d",&x);
        mp[i][j]=(x==0?1:0);
    }
    for(int i=2;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        if(mp[i][j]==1 && mp[i-1][j]>=1)
        mp[i][j]+=mp[i-1][j];
    }
    for(int i=1;i<=n;i++)
    mp[i][m+1]=0;

    // nn;
    // // for(int i=1;i<=n;i++)
    // // {
    // //     for(int j=1;j<=m;j++)
    // //     printf("%d ",mp[i][j]);
    // //     printf("\n");
    // // }
    //
    // nn;
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        int top=0;
        for(int j=1;j<=m+1;j++)
        {
            if(mp[i][j]>st[top].height)
            {
                st[++top].height=mp[i][j];
                st[top].width=1;
            }
            else
            {
                int w = 0;
                while(mp[i][j]<st[top].height)
                {
                    w+=st[top].width;
                    ans=max(ans,w*st[top].height);
                    top--;
                }
                st[++top].height=mp[i][j];
                st[top].width=w+1;
            }
            // printf("%d ",ans);
        }
        // memset(st,0,sizeof(st));
        // printf("\n");
    }
    // printf("\n");
    printf("%d\n",ans);
}
/*
4 5
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0
0 0 0 1 0

1 1 0 1 1
0 1 1 1 1
1 1 1 0 1
1 1 1 0 1
*/

// for(int i=1;i<=n;i++)
// {
//     for(int j=1;j<=m;j++)
//     printf("%d ",mp[i][j]);
//     printf("\n");
// }

这场打下来还是觉得挺有意思的hhhh

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值