3 条题解

  • 0
    @ 2026-9-2 1:59:57

    题面很好理解,不再赘述。

    解题思路

    主要分为 44 个步骤。

    Step one 储存游戏结果

    int n, a, b, p[205],q[205], x, y;
    int k[5][5] = {{0, 0, 1, 1, 0},
                 {1, 0, 0, 1, 0},
    			   {0, 1, 0, 0, 1},
    			   {0, 0, 1, 0, 1},
    			   {1, 1, 0, 0, 0}};
    

    Step two 输入

    cin >> n >> a >> b;
    for (int i = 0; i < a; i++) 
    	cin >> p[i];
    for (int i = 0; i < b; i++) 
    	cin >> q[i];
    

    Step three 加减

    for (int i = 0; i < n; i++)
    {
        x += k[p[i % a]][q[i % b]];
        y += k[q[i % b]][p[i % a]];
    }
    

    Step four 输出

    cout << x << ' ' << y;
    

    看到了吗,我们把题目拆解成四个部分,每个部分都很简单、很基础。这题本身就不是很难,但如果遇到难题,思路也是将它拆解成几个你会写的代码,所谓的“难题”也就不难了,这和做数学题一个道理。

    代码

    #include <iostream>
    using namespace std;
    int n, a, b, p[205],q[205], x, y;
    int k[5][5] = {{0, 0, 1, 1, 0},
                    {1, 0, 0, 1, 0},
    			    {0, 1, 0, 0, 1},
    			    {0, 0, 1, 0, 1},
    			    {1, 1, 0, 0, 0}};
    int main() {
    	cin >> n >> a >> b;
    	for (int i = 0; i < a; i++) 
    		cin >> p[i];
    	for (int i = 0; i < b; i++) 
    		cin >> q[i];
    	for (int i = 0; i < n; i++) {
        	x += k[p[i % a]][q[i % b]];
        	y += k[q[i % b]][p[i % a]];
    	}
    	cout << x << ' ' << y;
    	return 0;
    }
    

    完结撒花。

    • 0
      @ 2025-10-8 16:53:26

      两数组和为N的方案数

      题目描述

      给定两个正整数数组A和B,长度分别为NA和NB,每个元素均为正整数。现需从A中选取一个非空子集,从B中选取一个非空子集,使得这两个子集的和相等且等于N,求满足条件的方案总数。

      输入输出格式

      • 输入:第一行包含三个整数N, NA, NB(0 < N ≤ 200,0 < NA ≤ 200,0 < NB ≤ 200);第二行包含NA个正整数(数组A);第三行包含NB个正整数(数组B)。
      • 输出:一个整数,表示满足条件的方案数。

      解题思路

      1. 动态规划计算子集和方案数:分别对数组A和B计算所有可能非空子集的和对应的方案数,记为dpA和dpB。
      2. 累加乘积:对于每个可能的和s(1 ≤ s ≤ N),将dpA[s]与dpB[s]相乘,累加所有乘积即为答案。

      代码实现

      #include <iostream>
      #include <vector>
      using namespace std;
      
      // 计算数组arr中所有非空子集和的方案数,maxSum为最大可能和N
      vector<int> countSubsetSums(const vector<int>& arr, int maxSum) {
          vector<int> dp(maxSum + 1, 0);
          dp[0] = 1; // 初始状态:空集
          for (int num : arr) {
              // 逆序遍历避免重复计算同一元素多次
              for (int s = maxSum; s >= num; s--) {
                  dp[s] += dp[s - num];
              }
          }
          dp[0] = 0; // 排除空集
          return dp;
      }
      
      int main() {
          int N, NA, NB;
          cin >> N >> NA >> NB;
          vector<int> A(NA), B(NB);
          for (int i = 0; i < NA; i++) {
              cin >> A[i];
          }
          for (int i = 0; i < NB; i++) {
              cin >> B[i];
          }
          
          vector<int> dpA = countSubsetSums(A, N);
          vector<int> dpB = countSubsetSums(B, N);
          
          int result = 0;
          for (int s = 1; s <= N; s++) {
              result += dpA[s] * dpB[s];
          }
          
          cout << result << endl;
          return 0;
      }
      
      • 0
        @ 2025-10-8 16:53:08

        对于 100%的数据,0 < N ≤ 200,0 < NA ≤ 200, 0 < NB ≤ 200。

        • 1

        [NOIP 2014 提高组] 生活大爆炸版石头剪刀布

        信息

        ID
        56
        时间
        1000ms
        内存
        128MiB
        难度
        6
        标签
        递交数
        16
        已通过
        13
        上传者