【模拟】Vijos P1005 超长数字串
题目链接:
题目大意:
无限的正整数按顺序拼接成字符串S(S=12345678910111213...),给你一个字符串A(len<=200)求这个字符串在S中最早出现的位置。
(答案超过long long ,无法用KMP,不要相信标签)
题目思路:
【模拟】
这题简直了!!!!!!大模拟啊。细节超级多。疯狂TLE+WA+RE了17次才AC。
第一次写了一整天没写过,放了好久,昨天又写了一整天(哎效率低下。)
首先分两种普遍的情况和两种特殊情况考虑。
普遍情况一是S串是由三段组成,头,尾和中间数字串,头尾可能不完全。这时候枚举中间数字串的长度和起始位置,就可以判断出最早出现的数字
(如:123[98 12399 124]00 99[8 999 1000 10]01 等)
(一开始我是想把这个再分情况考虑,发现有进位什么的太麻烦了后来直接把这个数压到高精度中,先-1判断和头是否匹配,再每次+1判断和后面的字符串匹不匹配,尾部同理)
普遍情况二是S串是由两段组成,前面的数字的尾部和后面的数字的头部组成,这时要枚举重叠部分的长度和断开的位置。
(如:1[2 1]3 123[699 1237]00 60211602应该是 1[6021 1602]2 而不是[60211 602]12)
(一开始我忘记了这种情况WA了好久。。感觉自己好蠢。)
特殊情况一是全为0的情况,这是都不符合上面的情况,就需要在头部再添上一个1,肯定是最早出现的。
特殊情况二是全为9的情况,除了单个9是9以外,两位数以上的9都可以拆成 8[9999... 9]0000... 这个答案明显比[9999...] 10000...优。
(不知道自己还有没有漏情况,希望没有吧,望指教。)
//
//by coolxxx
//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<map>
#include<memory.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//#include<stdbool.h>
#include<math.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define eps (1e-8)
#define J 10
#define mod 1000000007
#define MAX 0x7f7f7f7f
#define PI 3.14159265358979323
#define N 404
using namespace std;
typedef long long LL;
int cas,cass;
int n,m,lll,ans;
double anss;
char s[N];
int a[N],b[N],t[N],c[N];
void gjdchange(int a[],int l,int r)//l~r中间的字符转化为高精度数a
{
int i;
mem(t,);
t[]=r-l+;
for(i=;i<=r-l+;i++)
t[i]=s[r-i+]-'';
memcpy(a,t,sizeof(t));
}
void plu(int a[])//高精度a+1
{
int i;
for(i=,a[]++;a[i]>=J;i++)
a[i]-=J,a[i+]++;
a[]=max(a[],i);
}
void dec(int a[])//高精度a-1
{
int i;
for(i=,a[]--;a[i]<;i++)
a[i]+=J,a[i+]--;
while(!a[a[]] && a[]>)a[]--;
}
int gjdbigger(int a[],int b[])//高精度a和高精度b比大小 1:a>b 0:a<b -1:a=b
{
if(a[]!=b[])return a[]>b[];
int i;
for(i=a[];i;i--)if(a[i]!=b[i])return a[i]>b[i];
return -;
}
bool tou(int i,int len)//判断头部是否满足
{
int ii;
dec(a);
for(ii=;ii<=a[] && i-ii;ii++)
if(a[ii]!=s[i-ii]-'')return ;
return ;
}
void gjdjia(int a[],int b[],int c[])//高精度a+高精度b,答案存在高精度c里
{
int i;
mem(t,);
t[]=max(a[],b[]);
for(i=;i<=t[];i++)
t[i]=a[i]+b[i];
for(i=;i<=t[];i++)
t[i+]+=t[i]/J,t[i]%=J;
while(t[t[]+])t[]++;
while(!t[t[]] && t[]>)t[]--;
memcpy(c,t,sizeof(t));
}
void gjdjian(int a[],int b[],int c[])//高精度a-高精度b,答案存在高精度c里
{
int i;
mem(t,);
t[]=a[];
for(i=;i<=t[];i++)
t[i]=a[i]-b[i];
for(i=;i<=t[];i++)
if(t[i]<)t[i+]--,t[i]+=J;
for(i=;i<=t[];i++)
t[i+]+=t[i]/J,t[i]%=J;
while(t[t[]+])t[]++;
while(!t[t[]] && t[]>)t[]--;
memcpy(c,t,sizeof(t));
}
void gjdchengdjd(int a[],int b,int c[])//高精度a*单精度b,答案存在高精度c里
{
int i;
mem(t,);
t[]=a[]+;
for(i=;i<=a[];i++)
t[i]=a[i]*b;
for(i=;i<=t[];i++)
t[i+]+=t[i]/J,t[i]%=J;
while(t[t[]+])t[]++;
while(!t[t[]] && t[]>)t[]--;
memcpy(c,t,sizeof(t));
}
void cal(int len,int head)//已知a为第一个完整出现的数字,len为长度,head为出现的位置
{
int i,j;
int tmp[N];
mem(tmp,);
//gjdchange(a,head,head+len-1);
b[]=;b[]=;c[]=;c[]=;
for(i=;i<a[];i++)
{
gjdchengdjd(b,i,tmp);
gjdjia(c,tmp,c);
b[b[]+]=;b[b[]++]=;
}
b[b[]]=;
b[]=a[];b[b[]]=;
for(i=;i<a[];i++)b[i]=;
gjdjian(a,b,a);
gjdchengdjd(a,len,b);
gjdjia(c,b,c);
mem(b,);
b[]=;b[]=head-;
while(b[b[]]>=J)b[b[]+]=b[b[]]/J,b[b[]++]%=J;
gjdjian(c,b,c);
}
void work(int &len,int &head)//从中间断开分成两个数字的情况
{
int i,j,l;
if(len<=n)
gjdchange(a,head,head+len-);
else a[]=MAX;
b[]=;
for(l=;l<=(n+)/+;l++)//最终长度n-l
{
for(j=;j<=l;j++)
if(s[j]!=s[n-l+j])break;
if(j<=l)continue;
for(i=l+;i<=n-l;i++)
{
b[]=;
for(j=i-;j;j--)b[++b[]]=s[j]-'';
for(j=n-l;j>=i;j--)b[++b[]]=s[j]-'';
plu(b);
if(b[b[]]==)continue;
for(j=;j<b[] && i+j<=n;j++)
if(b[b[]-j]!=s[i+j]-'')break;
if(j<b[] && i+j<=n)continue;
if(gjdbigger(a,b)){memcpy(a,b,sizeof(b));len=n-l;head=i;}
}
}
}
bool all9()//长度大于2且全是9的特殊情况 拆成8999999999...+9000000000...
{
int i;
gjdchange(b,,n);
for(i=;i<=b[];i++)if(b[i]!=)return ;
if(b[]==)return ;
b[b[]]=;plu(b);
memcpy(a,b,sizeof(b));
return ;
}
bool all0()//全是0的特殊情况 1+00000000...
{
int i;
gjdchange(b,,n);
for(i=;i<=b[];i++)if(b[i]!=)return ;
b[++b[]]=;
memcpy(a,b,sizeof(b));
return ;
}
void gjdprint(int a[])//输出高精度a
{
int i;
printf("%d",a[a[]]);
for(i=a[]-;i;i--)
printf("%d",a[i]);
puts("");
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);
#endif
int i,j,k,l;
// for(scanf("%d",&cas);cas;cas--)
// for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
while(~scanf("%s",s+))
// while(~scanf("%d",&n))
{
s[]='.';
n=strlen(s)-;
for(l=;l<=n;l++)
{
for(i=;i<=l && i+l-<=n;i++)
{
gjdchange(a,i,i+l-);
if(a[a[]]==)continue;//前导0不符合要求
if(i!=)
{
if(!tou(i,l))continue;
plu(a);
}
for(j=i+l;j<=n;j+=a[])
{
plu(a);
for(k=;j+k<=n && k<a[];k++)
{
if(a[a[]-k]!=s[j+k]-'')break;
}
if(j+k>n || k<a[])break;
}
if(j+k>n)break;
if(j>n)break;
}
if(i<=l && i+l-<=n)break;
}
//以上是将字符串拆成三段枚举,头,尾和中间的数字
work(l,i);
if(all9())cal(n,n);
else if(all0())cal(n+,);
else cal(l,i);
gjdprint(c);
}
return ;
}
/*
// //
*/
【模拟】Vijos P1005 超长数字串的更多相关文章
- 解决 PHPExcel 长数字串显示为科学计数
解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号. ...
- Openjudge 1.13-40 提取数字串按数值排序
40:提取数字串按数值排序 查看 总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个字符串,请将其中的所有数字串提取,并将每个数字串作为整数看待(假设可以用int 表示),按从 ...
- 解决 PHPExcel 长数字串显示为科学计数[转]
解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号. ...
- PHPExcel 长数字串显示为科学计数 与 其他错误
一.解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号 ...
- Codeforces 898 贪心关闭最少闹钟 优先队列最少操作构造N/2squares 讨论情况哈希数字串分割a+b=c
A /* Huyyt */ #include <bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define mkp(a,b) ...
- IT公司100题-25-求字符串中的最长数字串
问题描述: 实现一个函数,求出字符串中的连续最长数字串.例如输入”12345cbf3456″,输出”12345″. 函数原型为: void conti_num_max( const char * sr ...
- TYVJ P1063 数字串 Label:双指针 线性扫描
描述 给你一个长度为n的数字串,数字串里会包含1-m这些数字.如果连续的一段数字子串包含了1-m这些数字,则称这个数字字串为NUM串.你的任务是求出长度最短的NUM串是什么,只需要输出这个长度即可.1 ...
- parseInt在IE8转换返回不相等(parseInt("08")返回0等以0开头大于7的数字串)
描述 在IE8内核下parseInt("08")返回0,等以0开头大于7的数字串返回的值不相等 解决方法 parseInt当不指定radix时,当以0x开头时,s按照十六进制计算的 ...
- php导出CSV时,超长数字精度丢失问题与前导0的字符串丢失0的问题解决
php生成的CSV有时候会遇到两个特殊情况: 1.输出的字段中,含有超长数字(18位的数字)比方身份证:122121197410180016,就算输出时字段加上"",还是会被识别成 ...
随机推荐
- 如何使用Jquery获取Form表单中被选中的radio值
$("input[name='opType']:checked").val() -------此方法估计用的比较多,通俗易懂 $("input:radio:checke ...
- laydate时间组件在火狐浏览器下有多时间输入框时只能给第一个输入框赋值的问题
遇到的问题: laydate时间组件在火狐浏览器下有多时间输入框时只能给第一个输入框赋值的问题(safari下也有同样问题); 解决办法: 给laydate绑定id; 解决前代码: <input ...
- java编程思想-异常
DynamicFields类的setField方法里面的getField方法抛出的异常NoSuchFieldException 为什么是throw new RuntimeException(e);
- Android layout的横竖屏处理
一.layout-land和layout-prot的区别与使用 默认情况下,创建的Android项目里只有一个layout文件夹,尽管这样也可以横竖屏切换用,但是某些布局横屏过后闲的格外的丑,如下图 ...
- php中调用其他系统http接口的方法说明
使用函数: file_get_contents($url); 传入接口url及其参数:如 $url="http://192.168.1.1/test.jsp?id=1&type=2& ...
- Oracle AWR报告指标全解析-11011552
1-5 Top 5 Timed EventsWaits : 该等待事件发生的次数, 对于DB CPU此项不可用Times : 该等待事件消耗的总计时间,单位为秒, 对于DB CPU 而言是前台进程所消 ...
- 文字排版--字号、颜色(font-size, color)
可以使用下面代码设置网页中文字的字号为12像素,并把字体颜色设置为#666(灰色): body{font-size:12px;color:#666} 示例: <!DOCTYPE HTML> ...
- 安卓学习之ListView和GridView
ListView 和 GridView是安卓中显示信息的两个很基本也最常用的控件.他们的用法很相似,但是他俩也是有区别的. ListView显示的数据会将他的item放在一行显示,而且根据内容给出it ...
- python - zipfile
参考:http://www.cnblogs.com/sislcb/archive/2008/11/28/1342822.html zipfile - python处理zip文件的压缩与解压 ZipFi ...
- 关于点击空白关闭弹窗的js写法推荐?
$(document).mouseup(function(e){ var _con = $(' 目标区域 '); // 设置目标区域 ){ // Mark 1 some code... // 功能代码 ...