选取计数问题CSU 1759: Triangle(选三条边构成三角形)

举报
用户已注销 发表于 2021/11/19 01:17:50 2021/11/19
【摘要】 目录 CSU 1759: Triangle(选三条边构成三角形) CSU 1799 小Z的黑白棋 CSU 2049: 象棋 CodeForces 702B Powers of Two CSU 1759: Triangle(选三条边构成三角形) 题目: Description 给你长度为1~n n条边,请你求出有多少种组合...

目录

CSU 1759: Triangle(选三条边构成三角形)

CSU 1799 小Z的黑白棋

CSU 2049: 象棋

CodeForces 702B Powers of Two


CSU 1759: Triangle(选三条边构成三角形)

题目:

Description
给你长度为1~n n条边,请你求出有多少种组合方法数可以选出三条边构成三角形

Input
多组数据输入输出(数据组数考虑为最大可能性)
每组数据输入一个正整数n,表示有n条长度的边可供选择(n<=10000)

Output
每组数据输出可构成三角形的边的选择方法数

Sample Input
2
4
Sample Output
0
1

代码:
 


  
  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. long long n;
  6. while (cin >> n)cout << ((n - 1)*(n - 2)*(n - 3) / 6 + (n - 1) / 2 * (n / 2 - 1)) / 2 << endl;
  7. return 0;
  8. }

CSU 1799 小Z的黑白棋

题目:


Description

小Z有一些黑白棋,他觉得黑白混杂在一起极具美感,所以他总喜欢将这些棋子排成一排序列S1,但是小Y就喜欢跟小Z作对,她会趁小Z不注意偷偷将小Z最右边的棋子拿走,往他棋子序列的最左边添加一个白色的棋子形成一个新的序列S2来破坏小Z的美感。

S2(1~n) = 白棋+S1(i=1~n-1)

小Z总相信第一感,他认为他自己最初排好的序列S1是最完美的,新的序列S2会造成一定的破坏美感指数 = damage(S1) = S1与S2有多少个位置黑色与白色互不对应

Exp:

令白棋为a,黑棋为b :S1 = ababa  S2=aabab   damage(S1)=4

因为小Z有很多种摆放序列的方式,现在他希望让你帮他求所有摆放序列的方式会造成的damage(S1)的平均值

 

Input

多组数据输入输出

每组数据输入一个整数n和m表示白棋和黑棋的数量 0<=n , m<=1000,000,000 , 保证n+m>=1

Output

每组输出一个平均值答案,用最简分数表示,如果可以化简到整数,就用整数表示

Sample Input

1 1
Sample Output

3/2

这个题目的思想大约就是富比尼原理了。

n个白棋和m个黑棋有C(m+n,n)种排列。

其中,第一个棋子为黑棋的,有C(m+n-1,n)种

第i(i=1,2,3......m+n-1)个棋子和第i+1个棋子颜色不同的,有2*C(m+n-2,n-1)种

2*C(m+n-2,n-1)*(m+n-1)=2*n*C(m+n-1,n)

所以,本题答案是(1+2*n)*C(m+n-1,n)/C(m+n,n)=(1+2*n)*m/(m+n)

代码:
 


  
  1. #include<iostream>
  2. #include<stdio.h>
  3. using namespace std;
  4. long long gcd(long long a,long long b)
  5. {
  6. if(b==0)return a;
  7. return gcd(b,a%b);
  8. }
  9. int main()
  10. {
  11. int m,n;
  12. long long a,b;
  13. while(scanf("%d%d",&n,&m)!=EOF)
  14. {
  15. a=n+n+1;
  16. a*=m;
  17. b=m+n;
  18. if(a%b==0)printf("%d\n",a/b);
  19. else cout<<a/gcd(a,b)<<'/'<<b/gcd(a,b)<<endl;
  20. }
  21. return 0;
  22. }

CSU 2049: 象棋

题目:

Description
車是中国象棋中的一种棋子,它能攻击同一行或同一列中没有其他棋子阻隔的棋子。一天,小度在棋盘上摆起了许多車……他想知道,在一共N×M个点的矩形棋盘中摆最多个数的車使其互不攻击的方案数。他经过思考,得出了答案。但他仍不满足,想增加一个条件:对于任何一个車A,如果有其他一个車B在它的上方(車B行号小于車A),那么車A必须在車B的右边(車A列号大于車B)。
现在要问问你,满足要求的方案数是多少 。

Input
第一行一个正整数T,表示数据组数。( T<=10)
对于每组数据:一行,两个正整数N和M(N<=100000,M<=100000)。

Output
对于每组数据输出一行,代表方案数模1000000007(10^9+7)。

Sample Input
1
1 1
Sample Output
1


就是简单的计算组合数

代码:


  
  1. #include<iostream>
  2. using namespace std;
  3. const int m = 100000;
  4. int list[m], p[9592];//9592个素数
  5. void getp()//在p数组中存所有不超过m的素数
  6. {
  7. p[0] = 2;
  8. int key = 0;
  9. for (int i = 0; i < m; i++)list[i] = i % 2;
  10. for (int i = 3; i < m; i += 2)if (list[i])
  11. {
  12. p[++key] = i;
  13. for (int j = i + i; j < m; j += i)list[j] = 0;
  14. }
  15. }
  16. int degree(int m, int p)//求m!中素数p的次数
  17. {
  18. if (m)return degree(m / p, p) + m / p;
  19. return 0;
  20. }
  21. int main()
  22. {
  23. getp();
  24. int t, n, m, mi;
  25. cin >> t;
  26. while (t--)
  27. {
  28. cin >> n >> m;
  29. if (n < m)n ^= m ^= n ^= m;
  30. long long ans = 1;
  31. for (int i = 0; i < 9592; i++)
  32. {
  33. mi = degree(n, p[i]) - degree(m, p[i]) - degree(n - m, p[i]);
  34. while (mi--)ans = ans * p[i] % 1000000007;
  35. }
  36. cout << ans << endl;
  37. }
  38. return 0;
  39. }

CodeForces 702B Powers of Two

题目:

Description

You are given n integers a1, a2, ..., an. Find the number of pairs of indexes i, j (i < j) that ai + aj is a power of 2 (i. e. some integer xexists so that  ai + aj = 2^x).

Input

The first line contains the single positive integer n (1 ≤ n ≤ 10^5) — the number of integers.

The second line contains n positive integers a1, a2, ..., an (1 ≤ ai ≤ 10^9).

Output

Print the number of pairs of indexes i, j (i < j) that ai + aj is a power of 2.

Sample Input

Input
4
7 3 2 1
Output
2
Input
3
1 1 1
Output
3


  
  1. #include<iostream>
  2. #include<string.h>
  3. #include<algorithm>
  4. using namespace std;
  5. int list1[100001];
  6. int list2[100001];
  7. int n;
  8. long long f(int m)
  9. {
  10. for (int i = 0; i < n; i++)list2[i] = m - list1[n-1-i];
  11. long long sum = 0;
  12. long long temp1, temp2;
  13. for (int i = 0, j = 0; i < n && j < n;)
  14. {
  15. if (list1[i] < list2[j])i++;
  16. else if (list1[i] > list2[j])j++;
  17. else
  18. {
  19. temp1 = 1;
  20. temp2 = 1;
  21. while (i + 1 < n && list1[i + 1] == list2[j])
  22. {
  23. i++;
  24. temp1++;
  25. }
  26. while (j + 1 < n && list2[j + 1] == list1[i])
  27. {
  28. j++;
  29. temp2++;
  30. }
  31. sum += temp1*temp2;
  32. i++;
  33. j++;
  34. }
  35. }
  36. return sum;
  37. }
  38. int main()
  39. {
  40. cin >> n;
  41. int max = 0;
  42. for (int i = 0; i < n; i++)cin >> list1[i];
  43. sort(list1, list1 + n);
  44. int mi = 1;
  45. long long sum = 0;
  46. for (int i = 0; i < 30; i++)
  47. {
  48. mi *= 2;
  49. sum += f(mi);
  50. }
  51. for (int i = 0; i < n; i++)
  52. if (list1[i] == (list1[i] & (-list1[i])))sum--;
  53. cout << sum / 2;
  54. return 0;
  55. }

 

 

 

 

 

文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nameofcsdn/article/details/115922107

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。