题意



分析

考场爆零做法

考虑位数少的一定更小,高位小的一定更少。

然后计算一定位数下不同数字的个数,然后从高到低依次确定数位。

特例:如果确定的高位的后缀出现了x,那么要把x调整到后缀去,这样一定更优。

然而这样做有问题,有重复的情况,譬如样例1的6666。

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x)
{
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff; const int MAXN=2e3+7;
char X[MAXN],ans[MAXN];
int len;
ll n; int main()
{
freopen("python.in","r",stdin);
freopen("python.out","w",stdout);
scanf("%s",X+1);
len=strlen(X+1);
read(n); if(n==1)
{
puts(X+1);
return 0;
}
n-=1; int lim;
for(lim=1;;++lim)
{
ll sum=(ll)lim*9*pow(10,lim-1)+pow(10,lim);
cerr<<"lim="<<lim<<" sum="<<sum<<endl;
if(n>sum)
n-=sum;
else
break;
}
cerr<<"n="<<n<<" lim="<<lim<<endl;
for(int i=1;i<=lim;++i)
{
cerr<<"i="<<i<<endl;
for(int j=(i==1?1:0);j<=9;++j)
{
ll sum=(ll)(lim-i+1)*pow(10,lim-i);
// cerr<<" j="<<j<<" sum="<<sum<<endl;
if(n>sum)
n-=sum;
else
{
ans[i]=j+'0';
ans[i+1]=0;
break;
}
if(j==9)
abort();
}
cerr<<"ansi="<<ans[i]<<endl; if(i>=len&&strcmp(ans+i-len+1,X+1)==0)
{
// cerr<<"n="<<n<<endl;
int j;
for(j=lim+len;n;--j,n/=10)
{
ans[j]=n%10+'0';
}
for(;j>i;--j)
{
ans[j]='0';
}
puts(ans+1);
return 0;
}
}
printf("%s%s",ans+1,X+1);
// fclose(stdin);
// fclose(stdout);
return 0;
}

标解

毕姥爷太强了。

匹配字符串,考虑自动机上dp。

构造对x的KMP自动机,只是末尾位置的trans均指向末尾。

那么如果数字中出现过x,自动机上跑出来一定在末尾位置。

记\(f(i,j)\)表示从状态j走i步走到末尾位置上的方案数。写出转移方程:

\[f(i,j)=\sum_{k=0}^{9}f(i-1,\textrm{trans}(j,k))
\]

边界条件\(f(0,\textrm{maxstate})=1\)

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x)
{
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
typedef unsigned long long ull;
const ll INF=(1ULL << 63) - 1; const int MAXN=2e3+20;
char s[MAXN];
ll n; int nx[MAXN];
int trans[MAXN][MAXN]; ull f[MAXN][MAXN]; int main()
{
freopen("python.in","r",stdin);
freopen("python.out","w",stdout);
scanf("%s",s+1);
int l=strlen(s+1); // 处理next数组
int p=0;
for(int i=2;i<=l;++i)
{
while(p && s[p+1] != s[i])
{
p = nx[p];
}
if(s[p+1] == s[i])
{
++p;
}
nx[i]=p;
} for(int i=0;i<l;++i) // 处理trans转移数组
for(int j=0;j<10;++j)
{
p = i;
while(p && s[p + 1] != j + '0')
{
p = nx[p];
}
if(s[p + 1] == j + '0')
{
++p;
}
trans[i][j] = p;
}
for(int i=0;i<10;++i)
{
trans[l][i]=l;
} f[0][l]=1;
for(int i=1;i<2015;++i) // 2015是估计值
for(int j=0;j<=l;++j)
for(int k=0;k<10;++k)
{
f[i][j] += f[i-1][trans[j][k]];
if(f[i][j] > INF)
{
f[i][j] = INF;
}
} read(n);
int lim;
for(lim=1;lim < 2015 && f[lim][0] < n;++lim);
p=0;
for(int i=lim,j;i;--i)
{
for(j=0;j<10;++j)
{
if(n > f[i-1][trans[p][j]])
n -= f[i-1][trans[p][j]];
else
break;
}
printf("%d",j);
p = trans[p][j];
}
puts("");
// fclose(stdin);
// fclose(stdout);
return 0;
}

test20181016 B君的第一题的更多相关文章

  1. test20181017 B君的第一题

    题意 分析 考场做法 对p的幂打表发现,我们一定可以把x和y的二进制位从低到高依次调整成0. 具体而言,从0次幂开始每两个分为一组a,b,那么0,a,b,a+b组合中的一种可以将x,y的对应二进制位都 ...

  2. test20181016 B君的第二题

    题意 分析 考场暴力50分. 考虑bfs序,一个点的儿子节点的bfs序一定连续,所以对bfs序建线段树,努力打一下就行了. 时间复杂度\(O(n \log n + m \log n)\) #inclu ...

  3. test20181018 B君的第一题

    题意 分析 考场爆零做法 考虑dp,用\(f(i,j,0/1)\)表示i及其子树中形成j个边连通块的方案数,其中i是否向外连边. \(O(n^3)\),转移方程太复杂就打挂了. #include< ...

  4. test20181020 B君的第一题

    题意 分析 二次剩余问题. x,y相当于二次方程 \[ x^2-bx+c=0 \mod{p} \] 的两根. 摸意义下的二次方程仍然考虑判别式\(\Delta=b^2-4c\). 它能开根的条件是\( ...

  5. test20181019 B君的第一题

    题意 分析 考场做法同标解. 画图模拟分析发现,无论操作顺序怎样,操作数的奇偶性是不变的. 所以等同求出,以每点为根的操作数奇偶性. 用\(f(x)\)表示x及其子树中的边,包括x到它fa的边,将他们 ...

  6. [算法 笔记]2014年去哪儿网 开发笔试(续)第一题BUG修正

    上一篇的blog地址为:http://www.cnblogs.com/life91/p/3313868.html 这几天又参加了一个家公司的笔试题,在最后的编程题中竟然出现了去哪儿网开发的第一题,也就 ...

  7. 《学习OpenCV》练习题第五章第一题ab

    这道题是载入一幅带有有趣纹理的图像并用不同的模板(窗口,核)大小做高斯模糊(高斯平滑),然后比较用5*5大小的窗口平滑图像两次和用11*11大小的窗口平滑图像一次是否接近相同. 先说下我的做法,a部分 ...

  8. 《学习OpenCV》练习题第四章第一题b&c

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  9. 《学习OpenCV》练习题第四章第一题a

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

随机推荐

  1. WPF编程学习 —— 样式

     本文目录 1.引言 2.怎样使用样式? 3.内联样式 4.已命名样式 5.元素类型样式 6.编程控制样式 7.触发器 1.引言 样式(Style),主要是用来让元素或内容呈现一定外观的属性.WPF中 ...

  2. English trip -- VC(情景课)5 B Places around town 城市设施

    Vocabulary focus 核心词汇  drugstore  药店:    pill  n. 药丸:弹丸,子弹:口服避孕药         medicine  n. 药:医学:内科:巫术 hos ...

  3. python-day21--序列化模块模块

    什么叫序列化——将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化   序列化的目的: 1.以某种存储形式使自定义对象持久化: 2.将对象从一个地方传递到另一个地方. 3.使程序更具维护性. ...

  4. HDU-3631 Shortest Path (floyd)

    Description When YY was a boy and LMY was a girl, they trained for NOI (National Olympiad in Informa ...

  5. SQL语句增加列、修改列类型、修改列、删除列

    1.增加列: alter table tableName add columnName varchar(30) 2.修改列类型: alter table tableName alter column ...

  6. ASP.NET的内置对象 —— Response 对象

    在 ASP.NET 中,页面实际上是一个输出 HTML 的可执行对象. 传统的 ASP 程序通常将 ASP 代码和 HTML 标签集成在一个文件中,或者将其分离于多个文 件. 当执行文件时,服务器回从 ...

  7. OC Copy基本使用(深拷贝和浅拷贝)

     首先,什么是copy? Copy的字面意思是“复制”.“拷贝”,是一个产生副本的过程. 常见的复制有:文件复制,作用是利用一个源文件产生一个副本文件. 特点:1.修改源文件的内容,不会影响副本文件: ...

  8. Vue面试题整理

    1:什么是MVVM MVVM是是Model-View-ViewModel的缩写,Model代表数据模型,定义数据操作的业务逻辑,View代表视图层,负责将数据模型渲染到页面上,ViewModel通过双 ...

  9. Oracle11g 查询长时间运行的SQL

    一.大量的查询 某些时候,因为SQL的问题,导致数据库的session大量积压,服务器的磁盘读增大,CPU使用率剧增.一般这种SQL,都是一些全表扫描.多表关联.报表或者排序类的SQL.这中情况很有可 ...

  10. docker(三)反正我不喜欢敲命令,daocloud.io管理你的docker,安装远程下载工具aria2 迅雷远程下载 xware

    1.登录daocloud.io 2.寻找合适的镜像 3.查看镜像信息并部署,它给出了一个运行命令,其中有用的只是-V,目录映射,映射了物理服务器的/tddownload到容器的/xware/tddow ...