描述

一个房间里有n盏灯泡,一开始都是熄着的,有1到n个时刻,每个时刻i,我们会将i的倍数的灯泡改变状态(即原本开着的现将它熄灭,原本熄灭的现将它点亮),问最后有多少盏灯泡是亮着的。

提示

范围:40%的数据保证,n<=maxlongint

100%的数据保证,n<=10^200

**********************************************************************

1.编个小程序,打表(1-30),可以看出规律         f(n)=sqrt(n)的下界。

2.思考如何求大整数的根号:两种思路:迭代法,例如二分法、牛顿迭代等;

打点法:精确计算,一步到位。笔算开平方法,我二姐教过我。真是太好了。

我只想简单说个大概:

i。从后往前,隔两位点一个小数点

ii。从前往后,试商,做差,落下来

3.打点法肯定速度非常快O(200*100)的复杂度:根最大是100位,每求一位最多200位的操作。这个过程需要用到大数乘法、减法、移位。

4.最后一点,在编大数运算时最好按照位数固定进行运算,这样虽然牺牲了一点效率,但可读性好、易于实现。

5.要背下来大数运算,不要只会抄scl,唯有如此,方能随用随写,剑心合一。

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
#define size 205
int n[205], ni;
int ans[205];
int now[205];
int two[205];
int mu[205];
void getTwo(){//two=(ans*2)<<1;
	memset(two, 0, sizeof(two));
	int i;
	for (i = 0; i < size; i++){
		two[i] += (ans[i] << 1);
		two[i + 1] = two[i] / 10;
		two[i] %= 10;
	}
	for (i = size - 2; i >= 0; i--)
		two[i + 1] = two[i];
}
void getNow(){
	int i;
	for (i = size - 3; i >= 0; i--){
		now[i + 2] = now[i];
	}
	now[1] = n[ni--];
	now[0] = n[ni--];
}
void mul(int k){//mu=two_k*k
	memset(mu, 0, sizeof(mu));
	int i;
	for (i = 0; i < size; i++){
		mu[i] += two[i] * k;
		mu[i + 1] = mu[i] / 10;
		mu[i] %= 10;
	}
}
int cmp(){//now-mu
	int i;
	for (i = size - 1; i >= 0; i--)
	if (now[i] != mu[i])
		return now[i] - mu[i];
	return 0;
}
void sub(){//now-mu
	int i;
	for (i = 0; i < size - 1; i++){
		now[i] -= mu[i];
		if (now[i] < 0){
			now[i + 1]--;
			now[i] += 10;
		}
	}
}
void getAns(){
	int i;
	for (i = size - 2; i >= 0; i--){
		ans[i + 1] = ans[i];
	}
	for (i = 9; i >= 0; i--){
		two[0] = i;
		mul(i);
		if (cmp() >= 0){
			ans[0] = i;
			sub();
			return;
		}
	}
}
void go(){
	while (ni >= 0){
		getTwo();
		getNow();
		getAns();
	}
}
int main(){
	freopen("in.txt", "r", stdin);
	char a[205];
	int i;
	for (i = 0; a[i]; i++);
	ni = i;
	memset(n, 0, sizeof(n));
	for (i = 0; i < ni; i++)
		n[i] = a[ni - 1 - i] - '0';
	if ((ni & 1) == 0)ni--;
	memset(ans, 0, sizeof(ans));
	memset(now, 0, sizeof(now));
	go();
	for (i = size - 1; ans[i] == 0; i--);
	for (; i >= 0; i--)cout << ans[i];
	return 0;
}

vijos-1447 开关灯泡-大整数开方算法的更多相关文章

  1. 【老鸟学算法】大整数乘法——算法思想及java实现

    算法课有这么一节,专门介绍分治法的,上机实验课就是要代码实现大整数乘法.想当年比较混,没做出来,颇感遗憾,今天就把这债还了吧! 大整数乘法,就是乘法的两个乘数比较大,最后结果超过了整型甚至长整型的最大 ...

  2. vijos - P1447开关灯泡 (大数模板 + 找规律 + 全然数 + python)

    P1447开关灯泡 Accepted 标签:CSC WorkGroup III[显示标签] 描写叙述 一个房间里有n盏灯泡.一開始都是熄着的,有1到n个时刻.每一个时刻i,我们会将i的倍数的灯泡改变状 ...

  3. 【vijos】1447 开关灯泡(高精度+特殊的技巧)

    https://vijos.org/p/1447 一开始想了想似乎只想到了与约数个数有关,即约数个数为奇数那么显然是亮的. 竟然没想到完全平方数..sad.. 在正因子中,只有完全平方数的正因子才是奇 ...

  4. 大整数算法[11] Karatsuba乘法

    ★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...

  5. 大整数算法[09] Comba乘法(原理)

    ★ 引子          原本打算一篇文章讲完,后来发现篇幅会很大,所以拆成两部分,先讲原理,再讲实现.实现的话相对复杂,要用到内联汇编,要考虑不同平台等等. 在大整数计算中,乘法是非常重要的,因为 ...

  6. C# 基于大整数类的RSA算法实现(公钥加密私钥解密,私钥加密公钥解密)

    但是C#自带的RSA算法类RSACryptoServiceProvider只支持公钥加密私钥解密,即数字证书的使用. 所以参考了一些网上的资料写了一个RSA的算法实现.算法实现是基于网上提供的一个大整 ...

  7. [转]大整数算法[11] Karatsuba乘法

    ★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...

  8. 从大整数乘法的实现到 Karatsuba 快速算法

    Karatsuba 快速乘积算法是具有独特合并过程(combine/merge)的分治算法(Karatsuba 是俄罗斯人).此算法主要是对两个整数进行相乘,并不适用于低位数(如 int 的 32 位 ...

  9. 算法笔记_034:大整数乘法(Java)

    目录 1 问题描述 2 解决方案 2.1 蛮力法   1 问题描述 计算两个大整数相乘的结果. 2 解决方案 2.1 蛮力法 package com.liuzhen.chapter5; import ...

随机推荐

  1. 虚拟机centos6.5 --安装jdk

    1.首先卸载默认安装的openjdk,如下 rpm -qa | grep java #查看当前是否已经安装了跟java有关的包 yum -y remove java #卸载 rpm -qa |grep ...

  2. 几种语言的CGI编程

    为了了解PHP.JSP.ASP出现之前人们写网站的方法,洒家研究了一波CGI,使用C.Python.batch.shell script语言写了几个简单的网页. CGI即通用网关接口,指web服务器调 ...

  3. KVM 介绍(5):libvirt 介绍 [ Libvrit for KVM/QEMU ]

    学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分 ...

  4. dedecms调用标签总结(一)

    dedecms 基本包含了一个常规网站需要的一切功能,拥有完善的中文学习资料,很容易上手,学习成本较低.学会dedecms 的模板修改.栏目新增.内容模型新增和常用的标签调用方法后,即便我们不懂 ph ...

  5. Java 对象和类

    1.对象 object 对象是可被感知的一个实体,有唯一的名称.有一组表现对象的状态属性和对象内在具有的行为能力.比如张三这个人,他有姓名.职业.眼睛等具体状态属性,能实施说.跑.吃等方法.对象,在j ...

  6. 网络之OSI&&TCP/IP比较

    共同点: 1.OSI和TCP/IP都采用了层次结构的概念 2.都能够提供面向链接(TCP)和无链接(UDP)两种通信服务机制 不同点: 1.前者7层,后者两层 2.对可靠性要求不同,TCP/IP要求高 ...

  7. U3D的飞船太空射击例子中,使用coroutine

    coroutine 协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈,局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西.线程与协同程序的主要区别在于,一个具有多线程的程序 ...

  8. webform:分页组合查询

    一个简单的分页组合查询页面 /// <summary> /// 查询方法 /// </summary> /// <param name="tsql"& ...

  9. linux下内网端口转发工具:linux版lcx [实现远程内网维护]

    这个工具以前使用的初衷是内网渗透,需要将内网ssh端口转发到外网服务器上.但这个工具同样适用于运维工程师进行远程内网维护. 当然这一切的前提是内网可以访问外网,检测方法当然就是直接ping 一个外网I ...

  10. EditText限制输入字符类型的几种方式

    最近的项目上需要限制EditText输入字符的类型,就把可以实现这个功能的方法整理了一下: 1.第一种方式是通过EditText的inputType来实现,可以通过xml或者Java文件来设置.假如我 ...