111. Very simple problem 每个测试点时间限制: 0.50 sec.
给你一个自然数X,输出平方小于或等于X的最大整数。
输入 输入包含一个自然数 X (1≤X≤101000).
输出 输出答案
样例输入 16
样例输出 4 |
================================华丽的分割线 ================================
第一眼,觉得是个水题,看了数据范围发现暴难!
我的第一个做法是,网上看到的一个:用X减1,再-3,再-5,再-7,再-2k-1,到小于0,输出K-1。
最开始觉得不行,后来试了一下,发现:1=1=1^2
1+3=4=2^2
1+3+5=9=3^2
...
1+...+2*k-1=k^2
感觉比下面要介绍的方法简单得多,尝试了一下,TLE了。。。。
然后就是笔算开根,看了半天才看懂,推荐个地方吧:
http://www.gaokw.com/gwy/xingce/4183.html,有图有解释,觉得不错。
再一个,我的代码应该好懂,因为函数都单独抽取出来了,没堆在一起,有面向对象的感觉,呵呵。
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define USE 4
#define INF 10000
#define MAX 500
typedef struct {
int num[MAX], len;
}bignum;
char str[1000];
bignum a, b, c;
void add(bignum *a, int k)
{
int i;
for(i = 1; i <= a->len; i++){
if(!k){
break;
}
a->num[MAX - i] += k;
k = a->num[MAX - i] / INF;
a->num[MAX - i] %= INF;
}
if(k){
a->num[MAX - i] = k;
a->len++;
}
}
void dec(bignum *a, bignum *b)
{
int i, j = 0;
int len = b->len;
for(i = 1; i <= len; i++){
a->num[MAX - i] = a->num[MAX - i] - b->num[MAX - i] - j;
j = 0;
while(a->num[MAX - i] < 0){
a->num[MAX - i] += INF;
j++;
}
}
if(j){
a->num[MAX - i] -= j;
}
for(i = a->len; i >= 1; i--){
if(a->num[MAX - i]){
break;
}
}
a->len = i;
}
void mul(bignum *a, int k)
{
int i, j = 0;
//考虑一个特殊情况, k=0时
if(k == 0){
memset(a, 0, sizeof(bignum));
return;
}
for(i = 1; i <= a->len; i++){
a->num[MAX - i] = a->num[MAX - i] * k + j;
j = a->num[MAX - i] / INF;
a->num[MAX - i] %= INF;
}
if(j){
a->num[MAX - i] = j;
a->len++;
}
}
void output(bignum *a)
{
int i;
printf("%d", a->num[MAX - a->len]);
for(i = a->len - 1; i >= 1; i--){
printf("%.*d", USE, a->num[MAX - i]);
}
printf("\n");
}
int com(bignum *a, bignum *b)
{
int i;
if(a->len != b->len){
return a->len - b->len;
}
for(i = a->len; i >= 1; i--){
if(a->num[MAX - i] != b->num[MAX - i]){
return a->num[MAX - i] - b->num[MAX - i];
}
}
return 0;
}
int getnum(int len)
{
static int start = 0;
int i, n = 0;
for(i = 0; i < len; i++){
n *= 10;
n += str[start + i] - '0';
}
start += len;
return n;
}
int check(int k)
{
memcpy(&c, &b, sizeof(b));
//c = (20 * b + k) * k;
mul(&c, k * 20);
add(&c, k * k);
if(com(&a, &c) >= 0){
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
int i, j, t, n;
scanf("%s", str);
n = strlen(str);
if(n & 1){
j = getnum(1);
}else{
j = getnum(2);
}
n = (n + 1) / 2;
t = sqrt(j);
add(&a, j - t * t);
add(&b, t);
for(i = 2; i <= n; i++){
mul(&a, 100);
add(&a, getnum(2));
for(j = 9; j >= 0; j--){
if(check(j)){
break;
}
}
dec(&a, &c);
mul(&b, 10);
add(&b, j);
}
output(&b);
return 0;
}