如此编码(第27次CCF计算机软件能力认证)

时间限制: 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∑n​ci−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解释

𝑖i1234567
𝑎𝑖ai​3520104310
𝑏𝑖bi​22157310
𝑐𝑖−1ci−1​1330030001200036000

子任务

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∑j​ci−1​×bi​其中 %% 表示取余运算。令 𝑗j 取不同的值,则有如下等式:𝑚 % 𝑐1=𝑐0×𝑏1𝑚 % 𝑐2=𝑐0×𝑏1+𝑐1×𝑏2𝑚 % 𝑐3=𝑐0×𝑏1+𝑐1×𝑏2+𝑐2×𝑏3⋯m % c1​m % c2​m % 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;
}
 

  • 26
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值