poj3006 Dirichlet's Theorem on Arithmetic Progressions

很显然这是一题有关于素数的题目。

注意数据的范围,爆搜超时无误。

这里要用到筛选法求素数。

筛选法求素数的大概思路是:

如果a这个数是一个质数,则n*a不是质数。(年轻的孩子们不要纠结于判断a是否为素数)

用一个数组实现就是:

memset(prime,true,sizeof(prime));

if (prime[i]) prime[i*j]=false;

部分程序如下:

const max=1000005;
bool prime[1000005];
memset(prime,true,sizeof(prime));
for(i = 3 ; i <= ::max ; i ++ )
{
for(j = 3 ; j <= ::max/i ; j ++)
{
if(prime[i])
{
prime[i * j] = false;
}
}
}

之后将中间进行小小的优化:

我们知道偶数中,除了2,其他的都是合数。

所以就可以将i++ 和 j++改成i+=2,j+=2;

再将除2以外的偶数判为false;以及注意一下特殊的值: 1和0是false;(要记住,c++的数组是从0~max的,所以0要考虑在内)

优化后的程序如下:

const int max = 1000005;
bool prime[1000005]={false}; memset(prime,true,sizeof(prime));
for(i = 3 ; i <= 1000 ; i += 2 )
{
for(j = 3 ; j <= ::max / i ; j += 2)
{
if(prime[i])
{
prime[i * j] = false;
}
}
}
for(i = 4 ; i <= ::max; i += 2 )
{
prime[i] = false;
}
prime[1] = prime[0] = false;

这样,这题就可以在我们拟好的素数表中找到第n个要求的素数。用一个简单的循环就可以搞定。。hoho

附上我的程序:

#include<iostream>
#include<cstring>
using namespace std;
const int max = 1000005;
bool prime[1000005]={false};
int main()
{
int i,a,d,n,j;
memset(prime,true,sizeof(prime));
for(i = 3 ; i <= 1000 ; i += 2 )
{
for(j = 3 ; j <= ::max / i ; j += 2)
{
if(prime[i])
{
prime[i * j] = false;
}
}
}
for(i = 4 ; i <= ::max; i += 2 )
{
prime[i] = false;
}
prime[1] = prime[0] = false; while(cin >> a >> d >> n,a != 0 && d != 0 && n != 0)
{
j = 0;
for (i = a; j < n; i += d)
{
if (prime[i])
{
j++;
}
}
cout << i - d << endl;
}
return 0;
}

(最后的题外话,不懂怎么搞的老是忘记 memset的时候要用cstring...← ←...哎。。还是太年轻了)

随笔- 76  文章- 0  评论- 653 

html5 Web Workers

 

虽然在JavaScript中有setInterval和setTimeout函数使javaScript看起来好像使多线程执行,单实际上JavaScript使单线程的,一次只能做一件事情(关于JavaScript单线程可以看看setTimeout()和setInterval() 何时被调用执行),看个简单的例子证明一下

<!DOCTYPE html>
<html>
<head>
<title>Web Workers</title>
</head>
<body>
<h1>Web Workers</h1> <script type="text/javascript">
setTimeout(function(){
console.log('timeout function');
},1000);
alert('do not close');
</script>
</body>
</html>

页面一运行就会弹出一个对话框,如果setTimeout是在另外一个线程运行,那么过一秒钟控制台就会打印“timeout function”,事实是只要不关闭对话框,控制台永远不会输出文字,这两句话确实是在一个线程内运行的。

这样的设计使JavaScript比较简单,但有时候也很令人烦恼,因为单线程的设计意味着JavaScript代码必须很快运行完,常见的问题就是一段复杂的JavaScript脚本会中断页面其它脚本执行,甚至会出现页面失去响应,这也就是为什么ajax的API要设计成异步的。

Web Workers

在html5规范中引入了web workers概念,解决客户端JavaScript无法多线程的问题,其定义的worker是指代码的并行线程,不过web worker处于一个自包含的环境中,无法访问主线程的window对象和document对象,和主线程通信只能通过异步消息传递机制。(《JavaScript权威指南》)

web worker

我们需要把希望单独执行的javascript代码放到一个单独的js文件中,然后在页面中调用Worker构造函数来创建一个线程,参数是该文件路径,参数存放如果是相对地址,那么要以包含调用Worker构造函数语句所在脚本为参照,如果是绝对路径,需要保证同源(协议+主机+端口)。这个文件不需要我们在页面使用script标签显示引用

var worker=new Worker('js/worker.js');

这时候这个文件就会被异步加载并在后台执行,创建成功地worker是酱紫的

我们可以看到worker对象只有两个属性,其实是两个回调函数句柄

  1. onerror:当worker运行出现错误,并且没有在worker中ing捕获,会在此捕获
  2. onmessage:当worker向主线程发送消息是调用

在其prototype内有两个重要方法

  1. postMessage:很熟悉的赶脚,之前我们介绍过window对象的postMessage()方法,woker的postMessage方法和window的比较类似,但参数略有不同,只需要传递消息内容就可以,而且支持所有JavaScript原生数据类型,当然不放心的话同样也可以序列化为字符串传递
  2. terminate:终止worker执行,有些worker执行比较慢,主线程可以主动终止其执行

简单的小例子

在一个页面显示0~10000内所有可以被n整除的数,当然我们不用i*n这种,要略微使计算显得复杂一些嘛

index.html

 1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Web Workers</title>
5 </head>
6 <body>
7 <h1>Web Workers</h1>
8
9 <div id="test" style="width:500px;"></div>
10 <script type="text/javascript">
11 var worker=new Worker('js/worker.js');
12 worker.postMessage({
13 n:69
14 });
15
16 worker.onmessage=function(e){
17 var test=document.getElementById('test').innerHTML=e.data;
18 };
19 </script>
20 </body>
21 </html>

/js/worker.js

function calc(n){
var result=[];
for(var i=1;i<10000;i++){
var tem=i;
if(i%n==0){
if(i%(10*n)==0){
tem+='<br/>';
}
result.push(tem);
}
} self.postMessage(result.join(' '));
self.close();
} onmessage=function(e){
calc(e.data.n);
};

好像有几点没提到

worker.onmessage

绑定主线程的message事件,当worker调用postMessage时方法时,绑定的事件处理程序会被调用到,传递来的数据可以使用MouseEvent的data属性获取,通过target属性还可以获取worker对象

self是什么

self是woker中对自身的引用,有些像this

close()

在worker内部调用close()方法效果和在外部调用worker实例的terminate()方法效果一样,终止worker运行

onmessage

在这个句柄内接收外部调用者传递的参数,参数可以通过e.data获取

self.postMessage()

没错通过这个方法我们可以在worker内把结果传递给主线程,主线程上绑定的message事件的处理程序会被调用

worker的作用域

web worker的简单用法就是这样,但有些姿势还是得了解一下。

全新的JavaScript环境

当一个Worker实例被创建的时候,它会在一个全新的JavaScript运行环境中,完全和创建worker的脚本分离开,即使我们传递的消息是引用类型它们也是复制传递的,修改worker中的参数不影响创建脚本中的参数。

importScripts()

我们可以通过importScripts()方法通过url在worker中加载库函数,

importScripts('utility/dialog.js','common/cookie.js');

方法可以接受多个url,相对地址的url以当前worker为参照,方法会按照参数顺序依次下载运行库函数,如果中间某个脚本出错,剩下的都不会被载入和执行,而且这个方法是同步的,只有所有脚本都加载、运行完后才会返回。

worker执行模型

worker线程从上到下同步运行它的代码,然后进入异步阶段来对事件及计时器响应,如果worker注册了message事件处理程序,只要其有可能触发,worker就一直在内存中,不会退出,但如果worker没有监听消息,那么当所有任务执行完毕(包括计数器)后,他就会退出。

web worker中可以使用什么

 前面提到在worker中不能使用window对象和docuemnt对象,那么能够使用什么呢

  • JavaScript的全局对象:JSON、Date()、Array
  • self自身引用
  • location对象,但是其属性都是只读的,改了也影响不到调用者
  • navigator对象
  • setTimeout()、setInterval()及其对应清除方法
  • addEventListener()、removeEventListener()

最后

web worker还支持sub worker和共享worker,这方面没有太仔细看,浏览器兼容性也不讨理想,有兴趣同学可以上网搜索研究一下。

 
 
分类: HTML5
 
分类: poj

Dirichlet's Theorem on Arithmetic Progression的更多相关文章

  1. Dirichlet's Theorem on Arithmetic Progressions 分类: POJ 2015-06-12 21:07 7人阅读 评论(0) 收藏

    Dirichlet's Theorem on Arithmetic Progressions Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  2. POJ 3006 Dirichlet's Theorem on Arithmetic Progressions (素数)

    Dirichlet's Theorem on Arithmetic Progressions Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  3. poj 3006 Dirichlet's Theorem on Arithmetic Progressions【素数问题】

    题目地址:http://poj.org/problem?id=3006 刷了好多水题,来找回状态...... Dirichlet's Theorem on Arithmetic Progression ...

  4. POJ 3006 Dirichlet's Theorem on Arithmetic Progressions 素数 难度:0

    http://poj.org/problem?id=3006 #include <cstdio> using namespace std; bool pm[1000002]; bool u ...

  5. poj 3006 Dirichlet's Theorem on Arithmetic Progressions

    题目大意:a和d是两个互质的数,则序列a,a+d,a+2d,a+3d,a+4d ...... a+nd 中有无穷多个素数,给出a和d,找出序列中的第n个素数 #include <cstdio&g ...

  6. 【POJ3006】Dirichlet's Theorem on Arithmetic Progressions(素数筛法)

    简单的暴力筛法就可. #include <iostream> #include <cstring> #include <cmath> #include <cc ...

  7. Dirichlet's Theorem on Arithmetic Progressions POJ - 3006 线性欧拉筛

    题意 给出a d n    给出数列 a,a+d,a+2d,a+3d......a+kd 问第n个数是几 保证答案不溢出 直接线性筛模拟即可 #include<cstdio> #inclu ...

  8. Dirichlet's Theorem on Arithmetic Progressions

    http://poj.org/problem?id=3006 #include<stdio.h> #include<math.h> int is_prime(int n) { ...

  9. (素数求解)I - Dirichlet&#39;s Theorem on Arithmetic Progressions(1.5.5)

    Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit cid=1006#sta ...

随机推荐

  1. NYNU_省赛选拔题(8)

    题目描述 一天萌萌哒孟孟学长去博物馆参观,他想看到更多的东西.博物馆可以表示为N × M细胞的一个矩形区域. “.”表示为路,“*”表示为墙壁,每个墙壁上面都挂有美丽的画卷.孟孟学长可以看到与他所在位 ...

  2. 《python源代码分析》笔记 pythonVM一般表达式

    本文senlie原版的.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.字节码指令 LOAD_CONST:从consts表中读取序号为i的元素并压入到执行时栈中 ...

  3. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改 ASP.NET MVC+EF框架+EasyUI实现权限管系列  (开篇)   (1):框架搭建    ...

  4. HDU 4932 Miaomiao&#39;s Geometry(推理)

    HDU 4932 Miaomiao's Geometry pid=4932" target="_blank" style="">题目链接 题意: ...

  5. eclipse打不开data目录解决的方法

    1.首先手机必须详细root权限.没有的话,先去root. 2.root过后若还是不能打开,下载一个R.E管理器,然后将须要打开的目录设置为可读.可写.可运行. 附图:

  6. SVN & Git (二)

    Git:是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.Git 是 Linus T ...

  7. Android实现“是否退出”对话框和“带图标的列表”对话框

    今天我们学习的内容是实现两种对话框(Dialog),第一种是询问是否退出对话框,另外一种是带图标的列表对话框,程序的执行效果是,我们点击button1的时候,弹出第一种对话框,我们点击button2的 ...

  8. NPOI mvc easyui 根据Excel模板 生成Excel

    1.首先下载 NPOI  https://npoi.codeplex.com/releases  只要dll 就好 示例代码库太难懂了. NPOI 是一个开源  免费的 东西.而且不依赖 office ...

  9. Eclipse生成jsp 如何将GB18030 改成默认UTF-8

    前两天面试被问到了struts的问题,好久没用了准备复习下,用eclipse创建一个maven项目的时候发现创建的jsp文件都是GB18030编码的,如何更改为UTF-8呢,其实很简单,给各位分享一下 ...

  10. 一步一步写算法(之prim算法 下)

    原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉 ...