[关闭]
@Yeasion-Nein 2018-10-05T09:54:30.000000Z 字数 2922 阅读 718

10.4 Morning

Test


给一个数据组数T以及T组形如1926-08-17的日期,如果这个日期和1926-08-17的差值为质数或者0,输出"Niubi",否则输出"Haixing"。

(这个题一看就不可做) 模拟。完了。
总之呢,方法其一就是将两个日期中比较小的置为操作日期。然后就把较小的日期一步一步加到大的日期上面去。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. #define MAXN 100010
  6. #define Inf 0x7fffff
  7. #define LL long long
  8. using namespace std ;
  9. int Read(){
  10. int X = 0 ; char ch = getchar() ;
  11. while(ch > '9' || ch < '0') ch = getchar() ;
  12. while(ch >= '0' && ch <= '9')
  13. X = (X << 1) + (X << 3) + (ch ^ 48), ch = getchar() ;
  14. return X ;
  15. }
  16. int Is_Prime(int Now){
  17. if(Now == 0) return true ;
  18. if(Now == 1) return false ;
  19. if(Now == 2) return true ;
  20. for(int i = 2; i * i <= Now; i ++)
  21. if(Now % i == 0) return false ;
  22. return true ;
  23. }
  24. int Get_Day(int Now, int Y){
  25. if(Now == 1) return 31 ;
  26. if(Now == 3) return 31 ; if(Now == 4) return 30 ;
  27. if(Now == 5) return 31 ; if(Now == 6) return 30 ;
  28. if(Now == 7) return 31 ; if(Now == 8) return 31 ;
  29. if(Now == 9) return 30 ; if(Now == 10) return 31 ;
  30. if(Now == 11) return 30 ; if(Now == 12) return 31 ;
  31. if(Y % 4 != 0) return 28 ;
  32. if(Y % 100 == 0 && Y % 400 != 0)
  33. return 28 ;
  34. return 29 ;
  35. }
  36. int T, Year, Month, Day ;
  37. char Opt ; int Cnt ;
  38. int main(){
  39. T = Read() ;
  40. while(T --){
  41. Cnt = 0 ;
  42. scanf("%d-%d-%d", & Year, & Month, & Day) ;
  43. int GreatY = 1926 ;
  44. int GreatM = 8 ;
  45. int GreatD = 17 ;
  46. if(Year > GreatY || (Year == GreatY && Month > GreatM) || (Year == GreatY && Month == GreatM && Day > GreatD))
  47. swap(Year, GreatY), swap(Month, GreatM), swap(Day, GreatD) ;
  48. while(Year < GreatY || Month < GreatM || Day < GreatD){
  49. Cnt ++ ; Day ++ ;
  50. if(Day > Get_Day(Month, Year))
  51. Day = 1, Month ++ ;
  52. if(Month > 12)
  53. Month = 1; Year ++ ;
  54. }
  55. cout << Cnt << " " ;
  56. if(Is_Prime(Cnt)) puts("Niubi") ;
  57. else puts("Haixing") ;
  58. }
  59. return 0 ;
  60. }

给定一个大小为2N的圈子,其中有N对人是基佬,要求任意两个基佬的位置不相邻,求方案数。

我们可以很快知道对于一个有N个人的圈子可以有的排列顺序为,然后现在还有一些是可以经过令挖一些排序转转圈得来的,那么我们推算可以得到有重复的圈子种数是,然后没有重复段圈子总类数就是。那么我们想要从总的圈子种数里面减去一些不合法的种类。那么我们首先考虑至少有一对基佬坐在一起的情况。那么我们可以将这一对基佬看成一个,那么就剩下了个人,那么情况就有种,然后这两个基佬可以互换位置,那么就是种。
那么我们现在初步考虑的总方程好像是这样的:
种。但是我们要明白一个重复删减的问题。当我们考虑坐在一起的情况的时候,并没有限制其他人。那么假如在这里有一种情况是也坐在了一起,那么当我们枚举到了坐在一起的时候,也会出现一种也坐在一起的情况。而事实上,这两种情况是一样的,但是我们删减了两遍。所以我们要再加上一遍这个情况。其实这个也就是容斥原理。那么最后我们可以得出总方程为:

其中是从中选出i个数有多少种方案。最后的-1就是为了加上多减的哪些方案数。然后关于组合数的递推式子是这样的:,当然,在这之中还要用到逆元。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #define MAXN 100010
  6. #define Inf 0x7fffffff
  7. #define LL long long
  8. #define Mod 10000007
  9. using namespace std ;
  10. int Read(){
  11. int X = 0 ; char ch = getchar() ;
  12. while(ch > '9' || ch < '0') ch = getchar() ;
  13. while(ch >= '0' && ch <= '9')
  14. X = (X << 1) + (X << 3) + (ch ^ 48), ch = getchar() ;
  15. return X ;
  16. }
  17. int N, Ans ;
  18. int Times(int A, int B){
  19. int Ans = 1 ;
  20. while(B){
  21. if(B % 2 == 1) Ans = Ans * A % Mod ;
  22. A = A * A % Mod ;
  23. B >>= 1 ;
  24. }
  25. return Ans ;
  26. }
  27. int main(){
  28. N = Read() ;
  29. if(N == 1){
  30. puts("0") ; return 0 ;
  31. }
  32. int Erh = 1, Cnh = 1, Nh2 = 1 ;
  33. for(int i = 1; i <= 2 * N - 1; i ++)
  34. Nh2 *= i ;
  35. for(int i = 1; i <= N; i ++){
  36. int A = Erh * Cnh % Mod * Nh2 % Mod ;
  37. if(A % 2 == 1) Ans -= A ;
  38. else Ans += A ; Ans %= Mod ;
  39. if(i == N) break ; Erh <<= 1 ;
  40. if(Erh >= Mod) Erh -= Mod ;
  41. Cnh = Cnh * (N - i) % Mod * Times(i + 1, Mod - 2) % Mod ;
  42. Nh2 = Nh2 * Times(2 * N - i - 1, Mod - 2) % Mod ;
  43. }
  44. printf("%d\n", Ans) ; return 0 ;
  45. }

给定两个长度分别为, 串,下面有个操作分为两类:
1. 询问的区间为的子串中出现了几次。(可重叠)。
2. 将区间的互换。

某线段树。嗯。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注