题目描述
输入描述
输出描述
输入样例
2
12
60
输出样例
10
50
题目大意: 对于每个数字 x ,若该数字为奇数,则与 3 x + 1 相连,若为偶数,则与 x / 2 相连。现给定一个 n ,求( n ,n + 1 )区间内存在多少条相连的线段。
网络赛比网络之恭喜hdu进入71新纪元(bushi),ccpc (原)网络名额赛的签到题,赛上本来的想法是打表每个 n 对应的线段数量以找到规律,后来发现符合要求的线段其实满足以下两个条件:
①该线段的起始点 ≤ n;
②该线段的结束点 ≥ n+1;
此处只有区间端点问题需要纳入考虑范畴,例如当 n = 4 时,符合要求的应当是经过 4 ~ 5 区间的绳子,而对于绳子 1 ~ 4 在 4 处即停止了,此时并不符合要求。
由于该条件限制,可以考虑采用数学公式倒推的方法,将两种连接线段的方法分别进行讨论其符合条件的数目。例如,当 n = 12 时,以 x 与 2 x 连线的线段中满足条件的起始点有 7,8,9,10,11,12,共有 ( 12 + 1 ) / 2 个;以 x 与 3x + 1 连线的线段中满足条件的起始点有 5,7,9,11。同时需要注意的是,当 n 为 13 时,以 x 与 3x + 1 连线的线段中满足条件的起始点还包含了 13 ,因此对于该种方法需要进行特别的奇偶性判断。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=3e6+10;
const double pi=acos(-1);
int a[N],pos[N];
int main(){
int t;
cin>>t;
while(t--){
ll x,ans;
cin>>x;
ll b=(x+1)/3;
if(b%2==0)
b++;
if(x%2==0){
ans=(x-1-b)/2+1;
}
else if(x%2!=0){
ans=(x-b)/2+1;
}
if((x-1)%3==0&&((x-1)/3)%2!=0)
ans--;
ll a=(x+1)/2;
if(x&&1==0)a++;
//cout<<ans<<' '<<a<<endl;
cout<<ans+a<<endl;
}
return 0;
}