80分暴力
1 /*找规律80分TLE俩点 2 忘了啥规律了。 3 */ 4 5 #include<iostream> 6 #include<cstdio> 7 #include<cmath> 8 #include<cstring> 9 #include<algorithm> 10 #include<map> 11 #include<queue> 12 using namespace std; 13 14 long long n,now,ans,sum,tot; 15 16 inline void read(long long &num) 17 { 18 char c=getchar(); 19 for(;!isdigit(c);c=getchar()); 20 for(;isdigit(c);c=getchar()){num=num*10+c-'0';}; 21 } 22 23 int main() 24 { 25 //freopen("div.in","r",stdin); 26 //freopen("div.out","w",stdout); 27 read(n); 28 ans=now=1; 29 tot=4; 30 while(now<n) 31 { 32 if(sum==2) 33 { 34 sum=0; 35 now+=tot; 36 ans+=2; 37 tot+=2; 38 } 39 sum++; 40 } 41 if(n<=(now-((tot-2)>>1))) printf("%lld",ans-1); //在前一半 42 else printf("%lld",ans); //后一半 43 fclose(stdin); 44 fclose(stdout); 45 }
正解
1 /* 2 二分一个值,使之满足n <= x*(x+1)。 3 4 若(n/x)-(n/(x+1))<1,则说明n/x==n/(x+1),此时找一个最小的满足条件的x,此时这个x就是不重复的个数。 5 答案为互不不重复的个数L+重复的数的数字个数(n/r) 6 将(n/x)-(n/(x+1))<1 移项得到 n<=x*(x+1) 7 */ 8 9 #include<iostream> 10 #include<cstdio> 11 #include<cmath> 12 #include<cstring> 13 #include<algorithm> 14 #include<map> 15 using namespace std; 16 17 long long n; 18 19 bool check(long long x)//n<=x*(x+1) 20 { 21 if(x*1.0*(x+1)>1e18) return true; 22 if(n<=x*(x+1)) return true; 23 return false; 24 } 25 26 int main() 27 { 28 //freopen("div.in","r",stdin); 29 //freopen("div.out","w",stdout); 30 scanf("%lld",&n); 31 if(n==1) 32 { 33 puts("1"); 34 } 35 else if(n==2) 36 { 37 puts("2"); 38 } 39 else 40 { 41 long long L=1,R=n-1; 42 while(R-L>1) 43 { 44 long long mid=(L+R)/2; 45 if(check(mid)) R=mid; 46 else L=mid; 47 printf("%d ",L); 48 } 49 printf("%lld ",L+(n/R)); 50 } 51 return 0; 52 }