梯田AGAIN

来源:互联网 发布:数控车梯形螺纹g92编程 编辑:程序博客网 时间:2024/04/29 00:32

题目链接:点击打开链接

题目:

Description


大家还记得去年的梯田吗?土豪YZK在一块小岛上有着一大片n*m的梯田,每块1*1的田地都有它的高度。奴隶们不甘被YZK剥削,他们联合起来决定发动一场海啸淹掉YZK的部分梯田。

奴隶们去年尝试了一下,结果发现,由于土质太过松软,水能够透过土地渗入到相邻的梯田,即对于海啸高度h,梯田中所有小于等于h的土地都会由于土质松软而被被淹没。

现在给你一个n*m的矩阵,代表梯田中每块田地的高度。然后给定q个询问,每个询问给定一个海啸高度h,问在此高度下,不被淹没的梯田数量是多少。



Input


第一行一个整数T,表示测试数据组数。

对于每组测试数据:

第一行三个数字n,m,q,表示梯田的行数,列数和询问数。

之后n行,每行m个数字,表示每块田地的高度,梯田高度不大于1000000。

之后q行,每行给出一个海啸高度h,问大于这个高度的梯田有多少块。

0<T<20。

0<n,m<=200。

0<=q<1000。

0<=h<=1000000.


Output


对于每个询问,给出一个整数,表示大于这个海啸高度的梯田数量。

Sample Input


2
2 2 2
1 2
3 4
2
3
2 3 3
1 2 3
3 4 5
0
4
5

Sample Output


​2
1
6
1
0

题意分析:给你一个n*m的矩阵,有q次询问,每次给一个高度h,问大于该高度的数有多少个。

比赛的时候用的一维数组,然后排序,一个一个的数下,竟然过了!!!!然后回来在oj上提交就超时了^-^。正解为二分查找,不过可以直接使用upper_bound()函数。关于此函数有如下介绍:

函数
升序排列:
iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。
iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值<=key的最后一个元素的后一个元素。
降序排列:
iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值<= key的第一个元素。
iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值>=key的最后一个元素的后一个元素。
按照升序排序,然后ans = n*m-(upper_bound(a,a+n*m,h)-a)。当然也用其他的各种组合方案可以选择。

代码:

#include<set>#include<map>#include<list>#include<queue>#include<stack>#include<cmath>#include<vector>#include<cstdio>#include<stdlib.h>#include<iostream>#include<string.h>#include<algorithm>using namespace std;#define pb(a) push_back(a)#define mp(a,b) make_pair(a,b)#define in(a) scanf("%d",&a)#define mm(a,b) memset(a,b,sizeof(a))#define out(a) printf("%d\n",a)#define MOD =1e9+7#define ll long long#define INF 0x3f3f3f3f#define FOR(i,l,r) for(int i=l;i<=r;i++)int n,m,h[40005],q,H;int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&m,&q);        for(int i=0;i<n*m;i++)        scanf("%d",&h[i]);        sort(h,h+n*m);        while(q--)        {            scanf("%d",&H);            int ans=upper_bound(h,h+n*m,H)-h;            printf("%d\n",n*m-ans);        }    }    return 0;}



0 0