算法競賽入門經典 UVa815 Flooded!

說實話,剛看到這題有點蒙,沒有什麼思路,第一個蹦出來的東西居然是定積分那類的東西。

這一題我歷經千辛萬苦,可是最終還是WA,最開始完成提交之後TLE錯誤,重新修改了初始化就好了。之後提交是WA錯誤,發現在輸入1*1的情況下不能正常運行。幾經調試,感覺應該沒有什麼問題了。提交還是WA,然後在DEBUG裏找別人提供的數據,一項項覈對。發現一條不一樣的:

輸入:

2 2

66 75 

-21 -27

10481

輸出的高度是28.41,可是我輸出的數據爲28.40,進行單步調試,發現我的算法顯示的數據是28.4049999999,別人AC的程序算出來是28.4050000004,最後這0.01的誤差害死人,看來是算法本身就有問題。後來又嘗試吧上下界誤差改的比較小(1e-16)就顯示TLE錯誤,吧誤差稍微改大一些,就是WA錯誤。又嘗試修改輸出的是誤差的上界或下界,這個樣例過了,還是WA。

**************這是WA代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxd  35*35
using namespace std;
int a[maxd];

int qiugao(int i1,int a,int b)
{
	int c = (b-a)*100*i1;
	return c;
}

float qiugao2(int i,double r1,double a1,double a2, int rain)
{
	double c1 = (double)r1,c2 = (double)r1 + i*100.0*(a2-a1);
	double c3 = (double)(c1+c2)/2.0;
	double k;
	if(fabs(c3-rain)<1e-11)
	{
		return a2;
	}
	if(c3>rain)
	k = qiugao2(i,c1*1.0,a1*1.0,(a1+a2)*1.0/2.0,rain);
	else
	k = qiugao2(i,c3*1.0,(a1+a2)*1.0/2.0,a2*1.0,rain);
	return k;
}

int main()
{
	int m,n,rain,hight,kase=0;
	while(scanf("%d%d",&n,&m) == 2 && n)
	{
		hight =0;
		double hight1 =0;
		memset(a,0,sizeof(a));
		
		for(int i =0;i<m*n;i++)
		scanf("%d",&a[i]);
		scanf("%d",&rain);
		sort(a,a+m*n);
		int i =0;
		double per;
		if(m*n == 1)
		hight = rain/100.0;
		else
		for( int s = 1;s<m*n;s++)
		{
			hight += qiugao(s,a[s-1],a[s]);
		}
		
		if(rain>hight)
		{
			double k = (rain-hight)/(100.0*m*n);
			int t = a[m*n-1];
			printf("Region %d\nWater level is %.2lf meters.\n",++kase,t+k);
			printf("100.00 percent of the region is under water.\n\n");
		continue;
		}
		
		hight = 0.0;
		for( i = 1;i<=m*n;i++)
		{
			hight += qiugao(i,a[i-1],a[i]);
			if(hight>=rain)
			{
				int r1 = hight-(a[i]-a[i-1])*100*i;
				hight1 = qiugao2(i,r1,a[i-1],a[i],rain);
				per = i/(n*m*1.0);
				break; 
			}
		}

			printf("Region %d\nWater level is %.2lf meters.\n",++kase,hight1);
			printf("%.2lf percent of the region is under water.\n\n",per*100);
	}return 0;
}
下面是別人AC的代碼,自己也重新寫過,感覺這種思考方式真是妙,自己怎麼就沒有想到呢,思路清晰又簡單》就說簡簡單單的一步:把輸入的總雨量/100,這樣就直接把三維問題轉爲二維問題了。


#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
using namespace std;
#define INF 0x7fffffff

int h[35 * 35], n, m;
double v, H, k;

int main()
{
    int kase = 0;
    while(scanf("%d%d", &n, &m), n)
    {
        n *= m;
        for(int i = 0; i < n; i++)
            scanf("%d", h + i);
        h[n] = INF, n++;//加一個無窮大的數,是爲了在1*1的情況下也可計算 
        sort(h, h + n);
        scanf("%lf", &v);
        v /= 100.0;//這個相當於雨量全部在一個底爲10*10的長矩形體中 
        for(int i = 1; i <= n; i++)
        {//這一段畫圖比較好理解 
            v += h[i - 1];
            H = v / i;
            if(H < h[i])
            {
                k = i;
                break;
            }
        }
        printf("Region %d\n", ++kase);
        printf("Water level is %lf meters.\n", H);
        printf("%.2lf percent of the region is under water.\n\n", 100.0 * k / (n - 1));
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章