您的位置:首页 > 其它

SGU 111 Very simple problem 翻译 题解

2011-06-12 19:46 260 查看


111. Very simple problem

每个测试点时间限制: 0.50 sec.
每个测试点内存限制: 4096 KB

给你一个自然数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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: