发放激活码 (一问一答)

1、题目描述

题目描述 (来源于一问一答题目地址


完美世界最新的客户端游戏大作笑傲江湖最近已经开始测试了,由于希望参与的玩家太多,只能使用激活码的方式让一部分玩家可以参与测试,现在需要一个测试码的生成规则。
如从一组不重复的数字中获得随机几个数字组成验证码,其中只要是这些数字相加的和为相同的那么就认为是同一组验证码,最后希望获得一共有多少组有效验证码。 现在希望获得从一组N不同的数字中,获得和为C 的组个的个数。组合的个数有可能是1个 有可能是N个 。

输入格式

第一行输入1个整数M,表示总得数据组数。
第二行输入1个整数 2 < N < 100,表示需要输入的不同的数字的个数
第三行输入1个整数 C ,表示数字的和
第四行输入N个不同数字(数字>0)中间用逗号隔开,   0 < 单个数字 <= 100

测试格式

输入样例:

4
4
3
11 ,2, 3, 1
3
3
1,2,3
6
6
1, 6, 3, 2, 5, 4
10
10
1, 2, 3 ,4, 5, 6, 7 ,8 ,9 ,10
输出样例

2
2
4
10


2、算法及思想

将源数据按向量存储,在向量中选择部分数据使其和为C,用堆栈结构存储选择的数据,一直迭代,当栈为空的时候结束。流程如下:

    1. input N,C;
    2. vector<int> v(N), stack<int> s;         // 输入数据,并初始化
    3. s.push(v[0]), count=0                        // 将向量第一的数据压入栈底
    4. while  ! s.empty()
    5.      if s.top() < N-1
    6.              if   sum(s)  < C
    7.                        s.push(s.top()+1)         // 向堆栈加入下一个元素
    8.            else
    9.                       if  sum(s) == C             //存在一组,计数加一
    10.                              count ++
    11.                      s.top()++                      //栈顶加一
    12.      else
    13.             if   sum(s) == C              
    14.                        count++
    15.             s.pop()
    16.             s.top()++                // 弹栈后栈顶元素加一
    17.  print  count                     // 输出count.


3、C++代码实现

#include <iostream> #include <vector> #include <stack> using namespace std; int main() { int M; cin >> M; vector<int> v; stack<int> s; while(M–) { int N,C; cin >> N >> C; v.clear(); for(int i=0; i != N; i++) { int t; cin >> t; v.push_back(t); cin.get(); } int count = 0; int sum = 0; int temp; s.push(0); while( !s.empty() ) { sum += v[s.top()]; if (s.top()<N-1) { if (sum < C) s.push(s.top()+1); else { if(sum == C) count++; temp = s.top(); s.pop(); sum = sum-v[temp]; s.top()++; } } else //s.top()==N-1 { if(sum==C) count++; temp = s.top(); s.pop(); sum -= v[temp]; if(!s.empty()) { sum -= v[s.top()]; s.top()++; } } } cout << count << endl; } return 0; } 

点赞