1. 程式人生 > >演算法競賽中c++一些需要注意的錯誤

演算法競賽中c++一些需要注意的錯誤

1. 關於精度:

取整

  • 除法取整:
    • (除數為正)被除數為正時系統除法為向下取整,被除數為負時系統除法為向上取整。
    • 向上取整(被除數非負,除數為正):
      一般寫法(有bug):
    int cal(int x,int y)
    {
      return (x-1)/y+1;
    }

    上述寫法只適用於x為正的情況,x為0時有錯誤。
    正確寫法:

    int cal(int x,int y)
    {
      return x/y+(x%y!=0);
    }

    int cal(int x,int y)
    {
      return (x+y-1)/y;
    }
  • 庫函式(cmath庫)

    (返回值為double)
    向上取整:ceil(x);
    向下取整:floor(x);
  • 四捨五入:
LL cal(double x)
{
    return (x>=0.0)?(LL)(x+0.5):(LL)(x-0.5);
}
  • 除數為正通用:
    • 向上取整:
    int cal(int x,int y)
    {
      return (x>=0)?(x+y-1)/y:x/y;
    }
    • 向下取整:
     int cal(int x,int y)
     {
       return (x>=0)?x/y:(x-(y-1))/y;
     }

    賦值

  • 科學計數法:
LL inf=1e18+7;

上述寫法有錯,因為科學計數法為double型,由於精度問題,inf實際被賦值為1e18.
正確寫法:

LL inf=1000000000000000007LL;
  • double:
 double x=0.0;
  x=-x;
  cout<<x;

控制檯輸出為:\(-0\)

溢位

  • 位運算左移:
cout<<(1<<31);

控制檯輸出:\(-2147483648\)
正確寫法:

 cout<<(1LL<<31);

注意,以下寫法還是會溢位:

cout<<(1<<31LL);
  • 迴圈:
    因為int型變數溢位,以下迴圈無法退出:
for(int i=0;i<=2147483647;i++)if(i<0)cout<<"overflow";

2. 關於字串:

讀入:

  int x=1;
  char s[1];
  scanf("%s",&s);
  cout<<x;

輸入:a
控制檯輸出:0
這是因為讀入a之後還讀入了一個換行符,覆蓋了x的記憶體。所以,字元陣列最好不壓邊界開(除非用getchar)。

3. 關於編譯器:

報錯:

  • id returned 1:
    • 一種情況是該原始檔其可執行檔案正在執行
    • 另一種情況是主函式名拼錯了:
    int mian()
    {
     return 0;
    }

    執行:

    int main()
    {
    // \
    cout<<"hello world";
    return 0;
    }
    控制檯無輸出。
    在註釋後“\”這樣寫會跳過該行的下一行語句