【排序】【二分】【UVa 815】洪水(Flooded!)

原題傳送門
【問題描述】

  有一個n行m列的網格,每個格子是邊長爲10米的正方形,網格四周是無限高的牆壁,第i行第j列每個格子的海拔高度爲h[i][j]。現在網格中有T立方米的水,請你計算網格中的水平面的海拔高度,以及有水格子數目。注意,在網格中,所有有水格子的水平面的海拔高度相同,所以有水格子的數量爲海拔高度嚴格小於水平面高度的格子數目。

【輸入格式】
有多組數據,第一行整數n和m,表示網格有n行m列
接下來是n行m列的矩陣,第i行第j列的數字爲對應格子的海拔高度h[i][j]。
最後一行爲整數T,表示網格中水的體積。
輸入以0,0結束
【輸出格式】
第一行輸出“Region x”,(x表示當前數據的編號)
第二行爲”Water level is y meters.”其中y是最後的水位
第三行爲”z percent of the region is under water.“z表示有水格子的百分比。

【輸入樣例】

3 3
25 37 45
51 12 34
94 83 27
10000

【輸出樣例】

46.67
6

【數據範圍】

1<=n,m<=30
-1 000 000<=h[i][j]<=1 000 000
1<=T<=1 000 000 000

考試的時候確實沒想到排序的解法
正解是排序後依次按照格子各自的海拔累加一個總體積sum,直到總體積sum大於等於了T爲止,此時的水位就等於最後一個海拔h[j]+(sum-T)/100,
我當時覺得這個題不好做,但是題目說只有嚴格小於水位的格子才能被浸沒,想的二分猜這個水位t’,然後把大於等於t’的格子捨去,算一個總體積T’和原來的體積T比較,如果T’>T,則說明猜的水位太高,下次在更低的區間猜,沒想到居然對了。
注意Uva上原題輸入有負數海拔的存在,所以猜答案的區間應該是[-10000000,10000000]
這個題是我們考題,說收穫了什麼吧,很簡單,思維要開闊,不要侷限於一種做法,要一題多解。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<queue>
#include<cstring>
#include<algorithm>
#define maxn 35
#define eps 0.00000001
using namespace std;
int n,m;
double h[maxn][maxn];
double T;
bool check(double mid)
{
    double A=0,B=T/100;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)if(h[i][j]<mid)
    {
        A+=(mid-h[i][j]);
    }
    return A-B>eps;
}

int main()
{
    //freopen("my.in","r",stdin);
    //freopen("my.out","w",stdout);
    int re=0;
    while(1)
    {
    re++;
    memset(h,0,sizeof(h));
    scanf("%d%d",&n,&m);
    if(n==0 && m==0)break;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    scanf("%lf",&h[i][j]);

    scanf("%lf",&T);

    double A=-10000000,B=10000000,ans;
    for(int i=1;i<50;i++)
    {
        double mid=(A+B)/2;
        if(check(mid))B=mid,ans=mid;
        else A=mid;
    }

    printf("Region %d\n",re);
    printf("Water level is %.2lf meters.\n",ans);

    int cnt=0;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)if(h[i][j]<ans)
    cnt++;

    double per=(double)cnt/(double)(n*m)*100;

    printf("%.2lf percent of the region is under water.\n",per);
    printf("\n");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章