Cut The Wire(hdu7100)

原题链接

题目描述

在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

输入样例

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;
}

猜你喜欢

转载自blog.csdn.net/laysan/article/details/120084604
cut