洛谷P1014 Cantor表(二分 找规律)

题目大意:

解题思路:

额。。打表找规律,不需要真的模拟45°扫描,怎么找就各显各法了,大佬们找到了规律,10行就出来了,作为一名蒟蒻,只是看到了一些等差数列的规律。

废话:此题关键是提醒自己二分怎么写,注意边界情况,注意什么情况朝哪边移动。

代码(憋看了):

#include <iostream>
#include <vector>
#include <set>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <bitset>
#include <stack>
#include <stdint.h>
#define int long long
using namespace std;
int32_t main(){
	int n;
	cin>>n;
	if(n==1){
		cout<<"1/1"<<endl;return 0;
	}
	int up=n-1;
	int down=n-1;
	int x,y;
	x=1;y=1001;
	int ans=-1;
	while(x<y){
		int m=x+(y-x)/2;
		if(((2*m*m+3*m-up>=0) && (2*(m-1)*(m-1)+3*(m-1)-up<0))){
			ans=m;
			break;
		}
		if(2*m*m+3*m-up >0)y=m;
		if(2*m*m+3*m-up<0){
			x=m+1;
		}
	}
	int mount=2*ans+1;
	int upans=up;
	if(ans==1){
		if(up>mount){
			upans=mount-(up-mount);
		}
	}else{
		if(up-(2*(ans-1)*(ans-1)+3*(ans-1))<=mount)upans=up-(2*(ans-1)*(ans-1)+3*(ans-1));
		else{
			upans=mount-(up-(2*(ans-1)*(ans-1)+3*(ans-1))-mount);
		}
	}
	x=1;y=1001;
	ans=-1;
	while(x<y){
		int m=x+(y-x)/2;
		if(((3+m)*m/2-down>=0) && ((2+m)*(m-1)/2-down<0)){
			ans=m;
			break;
		}
		if((3+m)*m/2-down >0)y=m;
		if((3+m)*m/2-down<0){
			x=m+1;
		}
	}
	int downans;
	if(ans==1)downans=3-down;
	else if(ans%2==0){
		downans=down-(2+ans)*(ans-1)/2;
	}else {
		downans= 1+2*((ans/2)+1)-( down-(2+ans)*(ans-1)/2);
	}
	cout<<upans<<"/"<<downans<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值