閱讀461 返回首頁    go 阿裏雲 go 技術社區[雲棲]


poj 2006 Litmus Test 【即zoj 2351:計算酸的PH】

公式:  pH = -log10 [H+]  PH值根據氫離子濃度求出 ,【這裏的 [H+] 濃度是摩爾每升為單位的


Ka = [H+] [acid ions] / [acid]   平衡常數K等於分解的氫離子和酸根離子乘積與未分解的酸分子的比值 


輸入格式:   Ka :常數   ori :初始酸濃度    m :1摩酸分子完全溶解 分解出氫離子數    n :1摩酸分子完全溶解 分解出氫離子數【注意是完全溶解】

【這題需要特別注意的是】指數形式是可以直接輸入的。如用scanf 或者 printf要用%e輸入。 


題目給出了一個比較好的例子,用了甲酸的例子:甲酸的平衡常數Ka1.6 * 10-4,1摩爾甲酸完全溶解放出1摩爾 [H+] 和1摩爾酸根離子,如果初始濃度是0.1 moles/L,但是不知道確切有多少甲酸溶解了,設為x摩爾/L,最後平衡的時候,就有0.1 - x moles/L的甲酸分子(未溶解),[H+] 和酸根離子各 x moles/L。


注意:我上麵一直強調的兩個不同的概念,完全溶解和不完全溶解,完全溶解就是每個酸分子都水解成 [H+] 和酸根離子了,不完全溶解就是一個動態平衡的過程。我記得高中化學裏麵講到的,其實不存在完全水解的酸,就算是強電解質。。。回到題目上來,題目給出的m和n都是完全電解環境下,這樣就相當於給出了一個酸分子分解後的 [H+] 和酸根離子比例。比如m=2,n=1,就是2個 [H+] 和1個酸根離子,比如硫酸H2SO4。。。


這樣就可以設未知數列方程了,我們假設每L溶解了x摩爾的該酸,就有

Ka = mx*nx / ori-x ,變換以後就是 Ka*(ori-x) = mn*x*x ,再就是 mnx^2 + Ka*x - Ka*ori = 0,這樣就變成了一個一元二次方程,就可以開始解方程了。

x = [sqrt(Ka*Ka+4*m*n*Ka*ori)-Ka] / 2mn,這裏還沒完,因為我們隻是得到了每L溶解了x摩爾的該酸,還不是最後要求出的 [H+] ,所以還得乘上一個m。


消去分母裏麵的m,這樣才變成了大家博客裏麵津津樂道的:

i=-log10((sqrt(k*k+4*a*m*n*k)-k)/2/n);
printf("%.3f\n",i);

所以,要完全弄懂還是要花一番功夫的。另外多說一句,c語言中log是以e為底的,要想以10為底,要麼除以一個log((double)10)換底,要麼見下麵的代碼。


AC代碼:

#include<stdio.h>
#include<math.h>
#include<iostream>

using namespace std;

int main()
{
    double Ka;   //平衡常數
    double ori;  //原始酸濃度
    int m;       //1摩酸分子 完全溶解 分解出氫離子數
    int n;		 //1摩酸分子 完全溶解 分解出酸根離子數
    double H;    //最後計算Ph值的氫離子數
	
	while(1)
	{
		cin>>Ka;
		cin>>ori;
		cin>>m;
		cin>>n;

		if(Ka==0&&ori==0&&m==0&&n==0)
			break;

		H=(sqrt(Ka*Ka+4*m*n*Ka*ori)-Ka)/(2*n);
        printf("%.3f\n",-log10(H));
	}
	
	
	return 0;
}


寫博客,我覺得我得說實話,也順便發表一個感想。

這道題目是我做ACM以來遇到的最難理解題意的一道題,對於一個高中化學一塌煳塗,又腦袋不好使的我來說還是太難了,也可能是我本身就做題太少的緣故。。但是不論怎麼說,這道題的題意理解卻是難點。。

不過,我也遇到一個很有意思的現象,網上很多人說這道題水,可我讀這道題的題目就用了個把小時,看來是我智商太低呀,不然就是我英語太差,讀不懂題目。。。但是當我看到他們粘貼的代碼很相似(其中包括一些看似大牛的人),而對這題的題目沒有一個明確分析的時候(甚至隻粘貼了一個代碼在上麵),我大概明白了是怎麼回事了。。。做ACM還是得踏實啊,裝B不能當飯吃。。。


最後更新:2017-04-03 05:39:33

  上一篇:go mysql 清空二進製日誌
  下一篇:go wscript:329: error: Could not autodetect OpenSSL support. Make sure OpenSSL development packages are