开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
[传智杯 #5 初赛] E-梅莉的市场经济学
题目背景
梅莉这个学期选修了经济学。但是主修心理学的她实在不擅长经济领域的分析,为此她时常抱怨自己学不会,想退课。
但是如果现在退掉的话这学期的学分就不够啦,因此她根据“梦中”的经历,“胡诌”了一个简单到不现实的市场模型,并依据这个模型编起了 essay。为了方便地编出图表,她需要写一个程序来查询每个时刻的市场贸易差。
题目描述
市场每一天的贸易差可以视为一个有周期性规律的数列 : 具体而言, 可以被分为无穷段,第 段的内容为 。如下图所示,是将 数列内的前一些点绘制在坐标轴上的情况:
现在梅莉对市场发起了 次询问,每次她会给定一个 ,希望求出 是多少。
输入格式
- 第一行有一个正整数 ,表示询问次数。
- 接下来 行,每行一个正整数 ,描述每次询问。
输出格式
- 输出共 行。对于每次询问,输出对应的结果。
样例 #1
样例输入 #1
9
1
10
100
1000
10000
100000
1000000
10000000
100000000
样例输出 #1
0
1
6
-9
-11
-128
406
1629
5154
提示
对于所有数据,,。
分析
这题乍一看很复杂,其实很简单,但是当我看了一眼的范围,不禁还是啧了一下,看来不能用数组去存数,浅浅看一下,可以发现,这个是有规律的数学题,其实我们可以把这个数列分成不同的组,每一组可以发现就是个数字,于是前组一共有个数,很显然,每一组内部也是有规律的,规律就是先上升再下降,然后变成负数下降,再上升到,于是我们只需要确定每个的组别就行了,很简单,用二分可以判断出每个k的组别,然后后面的规律可以用语句很容易的找出。
代码
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <cstring>
#include <stack>
#include <cmath>
#include <algorithm>
#define int long long
using namespace std;
const int N=201000;
int f(int x){
return x*2*x-x;
}
signed main(){
int t;
cin>>t;
while(t--){
int q;
cin>>q;
int l=1,r=2e9+10;
while(l<r){
int mid=l+r>>1;
if(f(mid)<q){
l=mid+1;
}
else r=mid;
}
//cout<<l<<endl;
int g=l;
//cout<<g<<endl;
int loc=f(g)-q;
if(loc==0) cout<<0<<endl;
else{
//int sign=g-1;
loc=q-f(g-1);
//cout<<loc<<endl;
if(loc>=1 && loc <=g) cout<<loc-1<<endl;
else if(loc>g && loc<=2*g-1) cout<<2*g-1-loc<<endl;
else if(loc>=2*g && loc<=3*g-2) cout<<2*g-1-loc<<endl;
else if(loc>=3*g-1 && loc<=4*g-4)cout<<loc-(4*g-3)<<endl;
}
//if(q)
}
return 0;
}
希望能帮助到大家()!