问题描述
试题编号: | 202112-1 | ||||||||||||||||||||||
试题名称: | 序列查询 | ||||||||||||||||||||||
时间限制: | 300ms | ||||||||||||||||||||||
内存限制: | 512.0MB | ||||||||||||||||||||||
问题描述: | 题目背景西西艾弗岛的购物中心里店铺林立,商品琳琅满目。为了帮助游客根据自己的预算快速选择心仪的商品,IT 部门决定研发一套商品检索系统,支持对任意给定的预算 𝑥,查询在该预算范围内(≤𝑥)价格最高的商品。如果没有商品符合该预算要求,便向游客推荐可以免费领取的西西艾弗岛定制纪念品。 假设购物中心里有 𝑛 件商品,价格从低到高依次为 𝐴1,𝐴2⋯𝐴𝑛,则根据预算 𝑥 检索商品的过程可以抽象为如下序列查询问题。 题目描述𝐴=[𝐴0,𝐴1,𝐴2,⋯,𝐴𝑛] 是一个由 𝑛+1 个 [0,𝑁) 范围内整数组成的序列,满足 0=𝐴0<𝐴1<𝐴2<⋯<𝐴𝑛<𝑁。(这个定义中蕴含了 𝑛 一定小于 𝑁。) 基于序列 𝐴,对于 [0,𝑁) 范围内任意的整数 𝑥,查询 𝑓(𝑥) 定义为:序列 𝐴 中小于等于 𝑥 的整数里最大的数的下标。具体来说有以下两种情况:
此时序列 𝐴 中从 𝐴0 到 𝐴𝑖 均小于等于 𝑥,其中最大的数为 𝐴𝑖,其下标为 𝑖,故 𝑓(𝑥)=𝑖。
此时序列 𝐴 中所有的数都小于等于 𝑥,其中最大的数为 𝐴𝑛,故 𝑓(𝑥)=𝑛。 令 𝑠𝑢𝑚(𝐴) 表示 𝑓(0) 到 𝑓(𝑁−1) 的总和,即: 对于给定的序列 𝐴,试计算 𝑠𝑢𝑚(𝐴)。 输入格式从标准输入读入数据。 输入的第一行包含空格分隔的两个正整数 𝑛 和 𝑁。 输入的第二行包含 𝑛 个用空格分隔的整数 𝐴1,𝐴2,⋯,𝐴𝑛。 注意 𝐴0 固定为 0,因此输入数据中不包括 𝐴0。 输出格式输出到标准输出。 仅输出一个整数,表示 𝑠𝑢𝑚(𝐴) 的值。 样例1输入 Data 样例1输出 Data 样例1解释𝐴=[0,2,5,8]
如上表所示,𝑠𝑢𝑚(𝐴)=𝑓(0)+𝑓(1)+⋯+𝑓(9)=15。 考虑到 𝑓(0)=𝑓(1)、𝑓(2)=𝑓(3)=𝑓(4)、𝑓(5)=𝑓(6)=𝑓(7) 以及 𝑓(8)=𝑓(9),亦可通过如下算式计算 𝑠𝑢𝑚(𝐴): 样例2输入 Data 样例2输出 Data 子任务50% 的测试数据满足 1≤𝑛≤200 且 𝑛<𝑁≤1000; 全部的测试数据满足 1≤𝑛≤200 且 𝑛<𝑁≤107。 提示若存在区间 [𝑖,𝑗) 满足 𝑓(𝑖)=𝑓(𝑖+1)=⋯=𝑓(𝑗−1),使用乘法运算 𝑓(𝑖)×(𝑗−𝑖) 代替将 𝑓(𝑖) 到 𝑓(𝑗−1) 逐个相加,或可大幅提高算法效率。 |
这题按题中所说的判断方法慢慢来就行,注意n和N区别,不过写了发现运行超时,只有50分,然后才发现最下面有提示,要优化一下,其实也很简单,对着表格找规律就行,把A[i]带入例子试试,再调试一下就行了,不过小心i别超过数组大小了,虽然不会输出错误,但会输出一个毫无关联的数字,这里也提醒同学:如果输出了一个很大的数字,可能是数组的下标越界了或者数组的相应部分没有初始化。
代码如下:
#include<iostream>
using namespace std;
bool t(int x){
while(x>0){
if(x%10==7)return true;
x/=10;
}
return false;
}
bool hanyou(int x){
if(x%7==0){
return true;
}
if(t(x)){
return true;
}
return false;
}
int main(){
int n;cin>>n;
int a[4]={0};
int b[4]={0};
int i=0;//i模拟甲乙丙丁
int j=1;//j模拟报数
for(int k=1;k<=n;k++){
if(hanyou(j)){
a[i]=0;
b[i]++;
j++;
k--;
i++;
}
else{
a[i]=j;
j++;
i++;
}
if(i==4){
//cout<<a[0]<<a[1]<<a[2]<<a[3]<<endl;
i=0;
}
}
//cout<<a[0]<<a[1]<<a[2]<<a[3]<<endl;
cout<<b[0]<<endl;
cout<<b[1]<<endl;
cout<<b[2]<<endl;
cout<<b[3]<<endl;
}