题目大意:
解题思路:
额。。打表找规律,不需要真的模拟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;
}