UVa 12505 Searching in sqrt(n)

传送门

一开始在vjudge上看到这题时,标的来源是CSU 1120,第八届湖南省赛D题“平方根大搜索”。今天交题时CSU突然跪了,后来查了一下看哪家OJ还挂了这道题,竟然发现这题是出自UVA的,而且用的原题。

------------------------------------------------------------------------------------------------------------------

time limit 5s

In binary, the square root of 2, denoted by sqrt(2), is an infinite number 1.0110101000001001111... Given an integer n and a binary string (i.e. a string consisting of 0 and 1) S, your task is to find the first occurrence of S in the fraction part (i.e. the part after the decimal point) of sqrt(n). In case sqrt(n) is an integer, the fraction part is an infinite sequence of zeros.

Input

The first line contains T (T ≤ 100), the number of test cases. Each of the following lines contains an integer n (2 ≤ n ≤ 1, 000, 000) and a binary string S with at most 20 characters.

Output

For each case, print the position of the first character in the first occurrence of S. The first digit after the dot is at position 0. The answer is guaranteed to be no greater than 100.

Sample Input

2

2 101

1202 110011

Sample Output

2

58

----------------------------------------------------------------------------------------------------

Solution

高精度

O(N^3)

--------------------------------------------------------------------------------------------------

#include <bits/stdc++.h>
using namespace std;
const int N(300), M(125);
int get_len(int n){
    if(!n) return 1;
    int res=0;
    for(;n;res++,n>>=1);
    return res;
}
void trans(int n, int *bit, int &len){
    int l=get_len(n);
    for(int i=len+l-1; i>=len; i--){
        bit[i]=n&1, n>>=1;
    }
    len+=l;
}
int tmp[N], a[N], b[N], len, _len, LEN;
void sqr(){ //error-prone
    memset(tmp, 0, sizeof(tmp));
    for(int i=0; i<len; i++) for(int j=0; j<len; j++) tmp[i+j]+=a[i]*a[j];
    for(int i=2*len-2; i; i--){
        tmp[i-1]+=tmp[i]/2;
        tmp[i]%=2;
    }
    trans(tmp[0], b, LEN=0);
    for(int i=1; i<=2*len-2; i++) b[LEN++]=tmp[i];
}
int get_int(){
    int res=0, l=LEN-2*_len;
    for(int i=l-1, _pow=1; i>=0; res+=b[i]*_pow, i--, _pow<<=1);    //error-prone
    return res;
}
int solve(){
    int n; string s, t; cin>>n>>t;
    int m=sqrt(n);
    if(m*m==n) return 0;
    len=_len=0;
    trans(m, a, len);
    int tmp=len;
    while(_len<M){
        a[len++]=1, _len++;
        sqr();
        if(get_int()>=n) a[len-1]=0;
    }
    for(int i=tmp; i<len; i++) s+=‘0‘+a[i];
    return s.find(t);
}
int main(){
    //freopen("in", "r", stdin);
    int T;
    for(cin>>T; T--; cout<<solve()<<endl);
}

有意写得短一些,但还是有50行,太长了都不想看~

------------------------------------------------------------------------------

总结一下高精度度乘法的写法,虽说也没什么可总结的。

无论二进制还是十进制,写法都一样,以下代码结合题目按二进制写。

1. 大整数的存法:int[]数组,左边高位(左高右低即书写格式,这样处理有一定优越性(真的有优越性吗?)),0-indexed

2. 将长为n的大整数的a[]和长为m的大整数的b[]相乘

先按如下方式将长为n+m-1中间结果存在数组tmp[]

memset(tmp, 0, sizeof(tmp));
for(int i=0; i<n; i++)
    for(int j=0; j<m; j++)
        tmp[i+j]+=a[i]*b[j];

再处理出最终结果存到数组c[]

for(int k=i+j-2; k; k--)
    tmp[k-1]+=tmp[k]/2, tmp[k]%=2;

int get_len(int n){
    if(!n) return 1;
    int res=0;
    for(; n; res++, n>>=1);
    return res;
}

len=get_len(tmp[0]);
for(int i=len-1; i>=0; i--)
    c[i]=tmp[0]%2, tmp[0]/=2;

for(int k=1; k<i+j-1; k++)
    c[len++]=tmp[k];
时间: 2024-11-03 21:19:38

UVa 12505 Searching in sqrt(n)的相关文章

STL --- UVA 123 Searching Quickly

UVA - 123 Searching Quickly Problem's Link:   http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19296 Mean: 有一个字符串集合Ignore,还有一个文本集合TXT,在TXT中除了Ignore中的单词外其他的都是关键字,现在要你根据这些关键字来给TXT文本排序(根据关键字的字典). 注意:一行TXT文本中含多少个关键字就需要排多少次序,如果关键字的字典序相同则按照先后顺序来

UVA 12505 湖南省第八届大学生程序设计大赛原题 D - 平方根大搜索

D - 平方根大搜索 Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit Status Practice CSU 1114 Description 在二进制中,2的算术平方根,即sqrt(2),是一个无限小数1.0110101000001001111... 给定一个整数n和一个01串S,你的任务是在sqrt(n)的小数部分(即小数点之后的部分)中找到S第一次出现的位置.如果sqrt(

UVA - 123 Searching Quickly

题目链接 这道题就是给定 一系列ignore词(全部是小写),以::结尾 然后  输入一系列文本,每行不包括ignore词的作为关键词,(与ignore词比较不区分大小写) ,然后排序输出.每一行中可能出现几个关键词,那就以出现顺序先后输出,如果有几行包括了同一个关键词,就以输入时顺序输出,其余的按照字典序排序输出.输出的时候时候除了关键词大写外,其余都要小写. 这道题做的时候有点长,不过幸好1A. 我的思路是先把文本全部转化为小写,然后取出关键词,同时保存它的初始位置在哪一行以及在这一行出现的

uva 1597 Searching the Web

The word "search engine" may not be strange to you. Generally speaking, a search engine searches the web pages available in the Internet, extracts and organizes the information and responds to users' queries with the most relevant pages. World f

小白书练习题5.5.3 排序检索类、

UVA 340 Master-Mind Hints 题意:猜数字游戏,给n个数的序列给你.接下来一行是答案序列.剩下的都是猜测序列.对于每一个猜测序列,统计有多少个数字相同并且位置相同.有多少数字相同位置不同.每一个数字只能用一次. 思路:直接统计可以求出数字相同并且位置相同的哪一些数.在此过程中我加了一个标记数组.标记那些用过的数的位置为1,没用过为0:然后枚举猜测中哪些没用过的数字.去答案序列中找.当数字相等并且答案行中那个数也没用过时.计数加1: 1 #include<cstdio> 2

基于STL的字典生成模块-模拟搜索引擎算法的尝试

该课题来源于UVA中Searching the Web的题目:https://vjudge.net/problem/UVA-1597 按照题目的说法,我对按照特定格式输入的文章中的词语合成字典,以满足后期的快速查找. 针对于字典的合成途径,我利用了STL中的map与set的嵌套形成了一种特定的数据结构来解析文章中的单词 1 #include<map> 2 #include<iostream> 3 #include<set> 4 #include<algorithm

Searching Quickly UVA 123

说说:感觉这题目是做得越来越繁琐了.这道题基本上把接下来课设要做的英语词典的框架给做出来了.好像本题的解法就是所谓的倒排索引.先给你一系列的句子,其实就是一系列的词啦.当然里面要把一些词去掉.然后把剩下的每个词都做成索引.最后按字典序把所有词所在的句子都输出就可以了.我的做法是定义了一个结构index包含关键词和一个指针,该指针指向一个链表,链表中的每个节点包含了该关键词所在的句子的位置,以及该关键词在句子中的位置.然后读入词,若不是要忽略的词就判断该词是否已经在关键词表中,在则添加到相应关键词

UVa 11703 - sqrt log sin

题目:已知{xn}的递归公式,求x[n]. 分析:简单题.直接计算即可:x0 = 1:xi = x?i-sqrt(i)? + x?ln(i)? + x?i sin2(i)?. 说明:打表计算查询输出. #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> usin

Searching the Web UVA - 1597

链接:https://vjudge.net/problem/UVA-1597#author=0 这题写了我一个晚上,然后debug了一个早上.. 最主要就是AND那一部分,一开始用了一个很奇怪的方法实现,就是利用set递增的性质,设置一个cur变量保存现在遍历到的文章下标的最大值,然后检查s1和s2能否取到,cur每次取当前s1和s2的文章下标最大值.中间实现的时候也出了点bug,没有在遍历到末尾的时候跳出循环.然而这不是重点..重点在于cur不一定取到,也就是可以跳过cur取一个更大的值, 这