时间限制: 1.0 秒
空间限制: 512 MiB
题目背景
某次测验后,顿顿老师在黑板上留下了一串数字 2333323333 便飘然而去。 凝望着这个神秘数字,小 P 同学不禁陷入了沉思……
题目描述
已知某次测验包含 𝑛n 道单项选择题,其中第 𝑖i 题(1≤𝑖≤𝑛1≤i≤n)有 𝑎𝑖ai 个选项,正确选项为 𝑏𝑖bi,满足 𝑎𝑖≥2ai≥2 且 0≤𝑏𝑖<𝑎𝑖0≤bi<ai。 比如说,𝑎𝑖=4ai=4 表示第 𝑖i 题有 44 个选项,此时正确选项 𝑏𝑖bi 的取值一定是 00、11、22、33 其中之一。
顿顿老师设计了如下方式对正确答案进行编码,使得仅用一个整数 𝑚m 便可表示 𝑏1,𝑏2,⋯,𝑏𝑛b1,b2,⋯,bn。
首先定义一个辅助数组 𝑐𝑖ci,表示数组 𝑎𝑖ai 的前缀乘积。当 1≤𝑖≤𝑛1≤i≤n 时,满足:𝑐𝑖=𝑎1×𝑎2×⋯×𝑎𝑖ci=a1×a2×⋯×ai
特别地,定义 𝑐0=1c0=1。
于是 𝑚m 便可按照如下公式算出:𝑚=∑𝑖=1𝑛𝑐𝑖−1×𝑏𝑖=𝑐0×𝑏1+𝑐1×𝑏2+⋯+𝑐𝑛−1×𝑏𝑛m=i=1∑nci−1×bi=c0×b1+c1×b2+⋯+cn−1×bn
易知,0≤𝑚<𝑐𝑛0≤m<cn,最小值和最大值分别当 𝑏𝑖bi 全部为 00 和 𝑏𝑖=𝑎𝑖−1bi=ai−1 时取得。
试帮助小 𝑃P 同学,把测验的正确答案 𝑏1,𝑏2,⋯,𝑏𝑛b1,b2,⋯,bn 从顿顿老师留下的神秘整数 𝑚m 中恢复出来。
输入格式
从标准输入读入数据。
输入共两行。
第一行包含用空格分隔的两个整数 𝑛n 和 𝑚m,分别表示题目数量和顿顿老师的神秘数字。
第二行包含用空格分隔的 𝑛n 个整数 𝑎1,𝑎2,⋯,𝑎𝑛a1,a2,⋯,an,依次表示每道选择题的选项数目。
输出格式
输出到标准输出。
输出仅一行,包含用空格分隔的 𝑛n 个整数 𝑏1,𝑏2,⋯,𝑏𝑛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
样例2输入
4 0
2 3 2 5
样例2输出
0 0 0 0
样例3输入
7 23333
3 5 20 10 4 3 10
样例3输出
2 2 15 7 3 1 0
样例3解释
𝑖i | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
𝑎𝑖ai | 3 | 5 | 20 | 10 | 4 | 3 | 10 |
𝑏𝑖bi | 2 | 2 | 15 | 7 | 3 | 1 | 0 |
𝑐𝑖−1ci−1 | 1 | 3 | 300 | 3000 | 12000 | 36000 |
子任务
50%50% 的测试数据满足:𝑎𝑖ai 全部等于 22,即每道题均只有两个选项,此时 𝑐𝑖=2𝑖ci=2i;
全部的测试数据满足:1≤𝑛≤201≤n≤20,𝑎𝑖≥2ai≥2 且 𝑐𝑛≤109cn≤109(根据题目描述中的定义 𝑐𝑛cn 表示全部 𝑎𝑖ai 的乘积)。
提示
对任意的 1≤𝑗≤𝑛1≤j≤n,因为 𝑐𝑗+1,𝑐𝑗+2,⋯cj+1,cj+2,⋯ 均为 𝑐𝑗cj 的倍数,所以 𝑚m 除以 𝑐𝑗cj 的余数具有如下性质:𝑚 % 𝑐𝑗=∑𝑖=1𝑗𝑐𝑖−1×𝑏𝑖m % cj=i=1∑jci−1×bi其中 %% 表示取余运算。令 𝑗j 取不同的值,则有如下等式:𝑚 % 𝑐1=𝑐0×𝑏1𝑚 % 𝑐2=𝑐0×𝑏1+𝑐1×𝑏2𝑚 % 𝑐3=𝑐0×𝑏1+𝑐1×𝑏2+𝑐2×𝑏3⋯m % c1m % c2m % c3=c0×b1=c0×b1+c1×b2=c0×b1+c1×b2+c2×b3⋯
解决方案
#include <iostream>
using namespace std;
int main()
{
int n,m;
cin >> n;
cin >> m;
int a[n+1],b[n+1],c[n+1];
c[0] = 1;
int i,j;
for(i = 1;i<n+1;i++){
cin >> a[i];
c[i] = c[i-1]*a[i];
}
for(j=1;j<n+1;j++){
b[j] = (m%c[j]-m%c[j-1])/c[j-1];
cout<<b[j]<<" ";
}
return 0;
}