算法之暴力枚举(穷举)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/i_meteor_shower/article/details/81111154

枚举法的基本思想是根据题目的部分条件确定答案的大致范围,并在次范围内对所有可能的情况逐一验证,直到全部情况验证完毕。若某个情况验证符合题目的全部条件,则为本问题的一个解;若全部情况验证后都不符合题目的全部条件,则本题无解。也称为穷举法。

题目:某人有N袋金币,其中第i袋内金币的数量是Ai。现在他决定选出2袋金币送给小Hi,再选2袋金币送给小Ho,同时使得小Hi和小Ho得到的金币总数相等。他想知道一共有多少种不同的选择方法。

具体来说,有多少种下标四元组(i, j, p, q)满足i, j, p, q两两不同,并且i < j, p < q, Ai+ Aj = Ap + Aq。  

例如对于数组A=[1, 1, 2, 2, 2],一共有12种选法:

i j p q
1 3 2 4
1 3 2 5
1 4 2 3
1 4 2 5
1 5 2 3
1 5 2 4
2 3 1 4
2 3 1 5
2 4 1 3
2 4 1 5
2 5 1 3
2 5 1 4

input:

第一行包含一个整数N。  

第二行包含N个整数,A1, A2, A3 ... AN。

对于70%的数据,1 <= N <= 100  

对于100%的数据,1 <= N <= 1000, 1 <= Ai <= 1000000

eg:

5

1 1 2 2 2

output:

不同选择的数目。

eg:

12

代码举例:

  1. #include <iostream>
  2. #include <map>
  3. using namespace std;
  4. int main()
  5. {
  6.     int n;
  7.     cin >> n;
  8.     int a[1005];
  9.     long long con = 0;
  10.     map<int, int> mp1;
  11.     map<int, int> mp2;
  12.     for(int i = 0; i < n; i++)
  13.     {
  14.         cin >> a[i];
  15.         mp1[a[i]]++;
  16.     }
  17.     for(int i = 0; i < n; i++)
  18.     {
  19.         for(int j = (i+1); j < n; j++)
  20.         {
  21.             mp2[a[i] + a[j]]++;
  22.         }
  23.     }
  24.     for(int i = 0; i < n; i++)
  25.     {
  26.         for(int j = (i+1); j < n; j++)
  27.         {
  28.             if(a[i] != a[j])
  29.             {
  30.                 con += mp2[a[i] + a[j]] - mp1[a[j]] - mp1[a[i]] + 1;
  31.             }
  32.             else
  33.             {
  34.                 con += mp2[a[i] + a[j]] - mp1[a[j]] - mp1[a[i]] + 3;
  35.             }
  36.         }
  37.     }
  38.     cout << con << endl;
  39.     return 0;
  40. }

 穷举法是通过牺牲时间来换区答案的准确性与全面性。需要注意的是控制循环的次数,即时间复杂度。当语句执行达到10^8次时,大概是1s(1000ms)(ps:记住这个时间,以便在做题时判断大致时间,做到竟可能的保险)。

猜你喜欢

转载自blog.csdn.net/i_meteor_shower/article/details/81111154