ICPC World Finals 2018 Problem H Single Cut of Failure

題目連接 題解視頻 題解文檔html

解法概要: 問題能夠轉化爲ios

考慮一個長爲 $2n$ 的數組 $A$,$1$ 到 $n$ 這 $n$ 個整數每一個恰在 $A$ 中出現 $2$ 次。判斷是否存在一個長爲 $n$ 的子段使得 $1$ 到 $n$ 在其中各出現一次。git

這個經典問題可用雙指針在 $O(n)$ 的時間內解決。數組

這道題我 WA 到死,不是由於思路有漏洞,而是由於我不瞭解 std::cout函數

什麼是 IO manipulators

默認狀況下,cout 輸出浮點數的格式是 std::defaultfloatspa

下面咱們來看一下 defaultfloat 到底是個什麼東西。指針

defaultfloat 是一個 ios_base manipulator 。code

那麼 manipulator 是什麼呢orm

IO manipulator are helper functions that make it possible to control input/output streams using operator<< or operator>>.視頻

The manipulators that are invoked without arguments (e.g. std::cout << std::boolalpha; or std::cin >> std::hex;) are implemented as functions that take a reference to a stream as their only argument.(e.g. std::fixed is declared as ios_base& fixed(ios_base& str);)The special overloads of basic_ostream::operator<< and basic_istream::operator>> accept pointers to these functions.

The manipulators that are invoked with arguments (e.g. std::cout << std::setw(10);) are implemented as functions returning objects of unspecified type. These manipulators define their own operator<< or operator>> which perform the requested manipulation. Manipulators that take arguments are defined in the iomanip header. SOURCE

basic_ostream::operator<< 默認狀況下如何輸出浮點數

By default, floating-point values are printed using six digits of precision (1.55 printed as 1.55, 1.55667 printed as 1.55667, 3.1415926 printed as 3.14159); the decimal point is omitted if the value has no fractional part (e.g. 1.00 is printed as 1); trailing zeros are removed (e.g. 1.5000 printed as 1.5); and they are printed in eighter fixed or scientific notation depending on the value of the number. The library chooses a format that enhances readability of the number. Very large and very small values are printed using scientific notation. Other values are printed in fixed decimal.

總結: 默認狀況下(對應於 manipulator std::defaultfloat),basic_ostream::operator<< 輸出浮點數的格式爲: 最多 6 位數字(整數部分和小數部分加起來共 6 位,術語爲 precision 爲 6),具體而言

  • 若本來整數部分與小數部分位數之和就不超過 6 位,則原樣輸出,並去除 trailing zeros。
  • 若整數部分不超過 6 位,則先四捨五入去除多出小數部分再去除 trailing zeros。
  • 在上述兩種狀況中,若小數部分徹底被去除,則小數點也不輸出。
  • 若整數部分超過 6 位,則用科學記數法。

std::setprecision(n)std::fixed 的做用

setprecision(n) 的做用是將浮點數的輸出精度 (precision) 設爲 n。那麼這裏的 precision 到底是什麼意思呢?

By default, precision controls the total number of digits that are printed. When printed, floating-point values are rounded, not truncated, to the current precision. Thus, if the current precision is four, then 3.14159 becomes 3.142; if the precision is three, then it is printed as 3.14.

We can change precision by calling the precision by calling the precision member (function) or by using the setprecision manipulator. The precision member is overloaded. One version takes an int value and sets the precision to that new value. It returns the previous value. The other version takes no arguments and returns the current precision value. The setprecison manipulator takes an argument, which it uses to set the precision.


C++ Primer, 5th edition, pp 756

注意,這裏所說的 「rounded to the current precision」 具體仍然是按上面總結的方法操做。

std::fixed 控制浮點數的記數方式(這裏「記數方式」意思是「書寫方式」,不是計數方式,也不是精度),std::fixed 使得浮點數始終按十進制格式(fixed decimal,不理解 fixed 在這裏是什麼意思;fixed decimal 與 scientific notation 相對)輸出,也就是說較大的數或較小的數不用科學記數法了。

另外使用 fixed 這個 manipulator 以後,精度的含義也改變了。

These manipulators (fixed, scientific, hexfloat) also change the default meaning of the precision for the stream. After executing scientific, fixed, or hexfloat, the precision value controls the number of digits after the decimal point. By default, precision specifies the total number of digits——both before and after the decimal point.

總結

若是題目中要輸出浮點數,若指明保留幾位小數(例如 4 位小數),則在 main 函數的開頭加上一行

std::cout << std::fixed << std::setprecision(4);

若只寫

std::cout << std::fixed;

就是保留 6 位小數。

Reference

  1. https://www.uow.edu.au/~lukes/TEXTBOOK/notes-cpp/io/omanipulators.html
相關文章
相關標籤/搜索