CCF-CSP 202209 赛题练习
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF-CSP 202209 赛题练习相关的知识,希望对你有一定的参考价值。
CCF-CSP 202209 赛题练习
如此编码
已知某次测验包含 n 道单项选择题,其中第 i 题(1≤i≤n)有 ai 个选项,正确选项为 bi,满足 ai≥2 且 0≤bi<ai。比如说,ai=4 表示第 i 题有 4 个选项,此时正确选项 bi 的取值一定是 0、1、2、3 其中之一。
首先定义一个辅助数组 ci,表示数组 ai 的前缀乘积。当 1≤i≤n 时,满足:ci=a1×a2×⋯×ai
特别地,定义 c0=1。
m = c 0 ∗ b 1 + c 1 ∗ b 2 . . . . . m=c_0*b_1+c_1*b_2..... m=c0∗b1+c1∗b2.....
输入格式
从标准输入读入数据。
输入共两行。
第一行包含用空格分隔的两个整数 n 和 m,分别表示题目数量和顿顿老师的神秘数字。
第二行包含用空格分隔的 n 个整数 a1,a2,⋯,an,依次表示每道选择题的选项数目。
输出格式
输出到标准输出。
输出仅一行,包含用空格分隔的 n 个整数 b1,b2,⋯,bn,依次表示每道选择题的正确选项。
样例1输入
15 32767
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
样例1输出
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
#include<bits/stdc++.h>
using namespace std;
const int N = 21;
int n, m;
int a[N];
int b[N];
int c = 1, tc = 1;
int main()
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i < n; i++)
tc = a[i]*c; // 计算C1
cout << int((m%tc) / c) << ' '; // 除法相当于把前一个乘积减去了
c = tc;
return 0;
代码来源:Link
何以包邮?
输入n,n
本书,m:sum>=m
时包邮,求满足包邮的最低费用。
4 100
20
90
60
60
110
DFS
- 对于每本书,都有选和不选两种方案,可以对应一棵完全二叉树
- 遍历所有书的两种方案,找到最小值,采用dfs算法
#include<bits/stdc++.h>
using namespace std;
const int N = 35;
int n, x;
int price[N];
int ans = 1e9;
void dfs(int k, int sum)
if (sum >= x)
ans = min(ans, sum); // 更新最小值
if (k > n)
return;
dfs(k+1, sum + price[k]); // 选择这本书
dfs(k+1, sum); // 不选择
int main()
cin >> n >> x;
for (int i = 1; i <= n; i++)
cin >> price[i];
dfs(1, 0); // 从第一本开始
cout << ans;
return 0;
- 在思路二的基础上,对二叉树进行剪枝
- 剪枝思路:当前节点sum加上剩余节点的所有值之和已经小于x了,进行剪枝
- 求剩余节点的所有值,可以采用前缀和的思想
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 50;
int n,x;
int price[N];//价格
int sum_price[N];//前缀和
int ans = 1e9;
void dfs(int k,int sum)
if(sum+sum_price[n]-sum_price[k-1]<x)//sum_price[n]-sum_price[k-1]为剩余节点的所有值的和
return;
if(sum>=x)
ans = min(sum,ans);//更新最小值
if(k>n)
return;
dfs(k+1,sum+price[k]);//选择这本书
dfs(k+1,sum);//不选择这本书
int main()
cin>>n>>x;
for(int i=1;i<=n;i++)
cin>>price[i];
sum_price[i]=sum_price[i-1]+price[i];//前缀和
dfs(1,0);//从第一本书开始
cout<<ans<<endl;
代码来源:Link
DP思路
这个题就是一个01背包问题,书的价格既是价值又是体积。
注意用一个变量sum表示当前所有书的价格,这就是我们当前的体积
#include <bits/stdc++.h>
using namespace std;
const int N = 300010;
int n, m, v, sum;
int f[N];
int main()
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> v;
sum += v;
for (int j = sum; j >= v; j--)
f[j] = max(f[j], f[j - v] + v);
for (int i = m;; i++)
if (f[i] >= m)
cout << f[i];
break;
return 0;
Reference
加油!
感谢!
努力!
以上是关于CCF-CSP 202209 赛题练习的主要内容,如果未能解决你的问题,请参考以下文章