USACO fact4, spin

1、fact4

這個問題在《編程之美》上有過一個類似的問題,大概是求階乘 n! 後面有多少個0,最後可以轉換爲求[1,N]之間因子5有多少次。這個問題和fact4有點淵源,對於 n! 的尾數,看看規律就知道了:

1!  = 1
2!  = 2
3!  = 6
4!  = 24
5!  = 120
6!  = 720
7!  = 5,040
8!  = 40,320
9!  = 362,880
10! = 3,628,800
11! = 39,916,800
12! = 479,001,600
13! = 6,227,020,800
14! = 87,178,291,200
15! = 1,307,674,368,000
16! = 20,922,789,888,000


其實都是有 (n-1)! 的非0尾數與 n 乘積的尾數,唯一的麻煩是遇到了5,就會使得尾數變0,這時候要往進位去找新產生的尾數。好了,所有的 Trick 都在這了。我們看到題目指出 n 不大於4220 < 5^6,所以,代碼如下,注意那個pow

  1. #include <fstream>
  2. using namespace std;
  3.  
  4. ifstream fin("fact4.in");
  5. ofstream fout("fact4.out");
  6.  
  7. int N;
  8.  
  9. int main()
  10. {
  11.     fin >> N;
  12.  
  13.     int multiplier = 1pow = 100000, factor;
  14.     for(int i = 1; i <= N; ++i)
  15.     {
  16.         factor = i % pow;
  17.         multiplier = multiplier * factor;
  18.  
  19.         while(multiplier % 10 == 0)
  20.             multiplier /= 10;
  21.  
  22.         while(multiplier / pow > 0)
  23.             multiplier %= pow;
  24.     }
  25.  
  26.     fout << multiplier % 10 << endl;
  27.  
  28.     return 0;
  29. }



2、spin

單純樸素模擬,藉助STL的bitset來存儲輪子們的位置信息,因爲數據量實在是小,所以沒必要用線段樹來做時空優化了,要是用線段樹,肯定要快N倍吧。然後其實你不用bitset,直接開一個bool數組也是OK的。

  1. #include <fstream>
  2. #include <bitset>
  3. using namespace std;
  4. ifstream fin("spin.in");
  5. ofstream fout("spin.out");
  6.  
  7. #define PI 360
  8. int speed[6];
  9. bitset<PI> curr[6], next[6];
  10.  
  11. int main()
  12. {
  13.     int num, start, end;
  14.     for(int i=1; i<=5; i++)
  15.     {
  16.         fin >> speed[i] >> num;
  17.         for(int j = 1; j <= num; j++)
  18.         {
  19.             fin >> start >> end;
  20.             end += start;
  21.             for(int k = start; k <= end; k++)
  22.                 curr[i].set(k%PI);
  23.         }
  24.     }
  25.    
  26.     int angle = 0;
  27.     bool flag;
  28.     while(angle < PI)
  29.     {
  30.         for(int i = 0; i < PI; ++i)
  31.         {
  32.             flag = false;
  33.             for(int j = 1; j <= 5; j++)
  34.             {
  35.                 if(!curr[j].test(i))
  36.                 {
  37.                     flag = true;
  38.                     break;
  39.                 }
  40.             }
  41.             if(!flag)
  42.             {
  43.                 fout << angle << endl;
  44.                 return 0;
  45.             }
  46.         }
  47.        
  48.         for(int i = 1; i <= 5; i++)
  49.         {
  50.             for(int j = 0; j < PI; j++)
  51.                 next[i][j] = curr[i][(j+PI-speed[i])%PI];
  52.             curr[i]=next[i];
  53.         }
  54.        
  55.         ++angle;
  56.     }
  57.    
  58.     fout << "none" << endl;
  59.     return 0;
  60. }



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