9.5联合作战战果

来源:互联网 发布:bat 算法工程师 编辑:程序博客网 时间:2024/05/16 11:38

1.处理内容

字符串部

kmp 1题

trie 1题

AC自动机 1题

数学几何部

zz平面几何暴力 1题

快速幂裸版 1题

高斯消元 1题

动态规划部

裸01背包 1题

裸数位DP 1题

裸斜率优化DP 2题

2.字符串部

(1)kmp

照例甩题面http://codevs.cn/problem/1204/

直接甩代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>using namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(int x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}char a[111],b[111];int nxt[111],lena,lenb;signed main(){scanf("%s%s",a+1,b+1);lena=strlen(a+1);lenb=strlen(b+1);for(int i=2,j=0;i<=lenb;++i){while(j&&b[i]!=b[j+1]) j=nxt[j];if(b[i]==b[j+1]) ++j;nxt[i]=j;}for(int i=1,j=0;i<=lena;++i){while(j&&a[i]!=b[j+1]) j=nxt[j];if(a[i]==b[j+1]) ++j;if(j==lenb){write(i-j+1);return 0;}}return 0;}
(2)shortest prefixes

题面:给定n个单词,对于每个单词,求能够唯一表示该单词的前缀,如果没有则输出单词本身

    还是甩个链接http://poj.org/problem?id=2001

直接建trie树随便跑一跑就可以了

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>using namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(int x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}struct Dic{int nxt[26],tag;}dic[22222];char word[1111][22];int cnt,tot;void insert(char s[]){int pos=0,len=strlen(s+1);for(int i=1;i<=len;++i){++dic[pos].tag;if(!dic[pos].nxt[s[i]-'a'])dic[pos].nxt[s[i]-'a']=++cnt;pos=dic[pos].nxt[s[i]-'a'];}++dic[pos].tag;return ;}void get(char s[]){int pos=0,len=strlen(s+1),site=-1;for(int i=1;i<=len;++i){if(dic[pos].tag==1) break;printf("%c",s[i]);pos=dic[pos].nxt[s[i]-'a'];}return ;}signed main(){tot=1;while(scanf("%s",word[tot]+1)!=EOF){insert(word[tot]);++tot;}for(int i=1;i<=tot;++i){printf("%s ",word[i]+1);get(word[i]);puts(" ");}return 0;}

(3)文本生成器(JSOI2007)

题面:见链接http://www.lydsy.com/JudgeOnline/problem.php?id=1030

分析:利用容斥求不合法方案数,dp一下即可

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#define mod 10007using namespace std;inline long long read(){long long i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(long long x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}struct D{int son[26],tag,fail;}dic[6666];int now,n,m,f[111][6666],ans,redu;char word[111];void insert(){int len=strlen(word);int pos=0;for(int i=0;i<len;++i){if(!dic[pos].son[word[i]-'A'])dic[pos].son[word[i]-'A']=++now;pos=dic[pos].son[word[i]-'A'];}dic[pos].tag=1;return ;}void buildfail(){static int que[11111];int q=0;for(int i=0;i<26;++i)if(dic[0].son[i]) que[++q]=dic[0].son[i];for(int i=1;i<=q;++i){int nowpos,nxtpos,failpos;nowpos=que[i];for(int j=0;j<26;++j){failpos=dic[nowpos].fail;while(!dic[failpos].son[j])failpos=dic[failpos].fail;nxtpos=dic[nowpos].son[j];failpos=dic[failpos].son[j];if(nxtpos){dic[nxtpos].fail=failpos;if(dic[failpos].tag) dic[nxtpos].tag=1;que[++q]=nxtpos;}elsedic[nowpos].son[j]=failpos;}}}int ksm(int a,int b){int ret=1;while(b){if(b&1) ret=(ret*a)%mod;a=(a*a)%mod;b>>=1;}return ret;}signed main(){n=read();m=read();for(int i=1;i<=n;++i){scanf("%s",word);insert();}for(int i=0;i<26;++i)if(!dic[0].son[i]) dic[0].son[i]=++now;buildfail();f[0][0]=1;for(int i=1;i<=m;++i)for(int j=0;j<=now;++j){if(dic[j].tag||!f[i-1][j]) continue;for(int k=0;k<26;++k)f[i][dic[j].son[k]]=(f[i][dic[j].son[k]]+f[i-1][j])%mod;}ans=ksm(26,m);for(int i=1;i<=now;++i)if(!dic[i].tag)redu=(redu+f[m][i])%mod;write((ans-redu+mod)%mod);return 0;}
3.数学几何部

(1)line(bzoj1610)

著名的bzoj非权限第七页

来个著名dalao黄学长的题面链接http://hzwer.com/2602.html

随便瞎搞搞,几乎不动脑(set自带去重)

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<set>using namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(int x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}set<double> tank;int n,x[222],y[222];double xx,yy,slope;signed main(){n=read();for(int i=1;i<=n;++i){x[i]=read();y[i]=read();}for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j){xx=x[i]-x[j];yy=y[i]-y[j];slope=0;if(xx==0) slope=9999;else slope=yy/xx;tank.insert(slope);}write(int(tank.size()));return 0;}
(2)越狱(HNOI2008)

不告诉你题面是有n房m宗教,相邻房间宗教不同http://codevs.cn/problem/1851/

分析:依然容斥,今天是不是该改名叫容斥联合作战...

   总方案数-安全方案数即可

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#define mod 100003 using namespace std;inline long long read(){long long i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(long long x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}long long m,n; long long ksm(long long a,long long b){long long ret=1;while(b){if(b&1) ret=(ret*a)%mod;a=(a*a)%mod;b>>=1;}return ret;}signed main(){m=read();n=read();write((ksm(m,n)-(m*ksm(m-1,n-1)%mod)+mod)%mod);return 0;}
(3)著名模板题sphere球形空间产生器(JSOI2008)

经典高斯消元,直接甩链接http://www.lydsy.com/JudgeOnline/problem.php?id=1013

该题自带分析

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#define eps 1e-7using namespace std;inline long long read(){long long i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(long long x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}int n,m;double matrix[14][14],cur[14][14];void gauss(){for(int i=1;i<=n;++i){int maxn;double tmp;maxn=i;for(int j=i+1;j<=m;++j)if(fabs(matrix[j][i])>fabs(matrix[maxn][i])) maxn=j;if(maxn!=i)for(int j=1;j<=m;++j)swap(matrix[i][j],matrix[maxn][j]);tmp=matrix[i][i];for(int j=i+1;j<=m;++j)matrix[i][j]/=tmp;for(int j=1;j<=n;++j)if(j!=i){tmp=matrix[j][i];for(int k=i;k<=m;++k)matrix[j][k]-=matrix[i][k]*tmp;}}return ;}signed main(){n=read();m=n+1;for(int i=0;i<=n;++i)for(int j=1;j<=n;++j)scanf("%lf",&cur[i][j]);for(int i=1;i<=n;++i){int j=i-1;double d=0;for(int k=1;k<=n;++k){matrix[i][k]=(cur[i][k]-cur[j][k])*2;d+=(cur[i][k]+cur[j][k])*(cur[i][k]-cur[j][k]);}matrix[i][m]=d;}gauss();for(int i=1;i<=n;++i){if(matrix[i][m]<eps)printf("0.000");elseprintf("%.3lf",matrix[i][m]);if(i<n) putchar(' ');}return 0;}
4.动态规划部

(1)装箱问题(luoguP1049)

题意:对于容积V与n个占据空间分别为c[1],c[2]...c[n]的填充,求最小剩余容积

    其实是这样https://www.luogu.org/problem/show?pid=1049

分析:我都不想说什么...我什么都不想说...

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>using namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(int x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}int v,n,c[33],f[22222];signed main(){v=read();n=read();for(int i=1;i<=n;++i)c[i]=read();f[v]=true;for(int i=1;i<=n;++i)for(int j=c[i];j<=v;++j)if(f[j]==true)f[j-c[i]]=true;for(int i=0;i<=v;++i)if(f[i]==true){write(i);return 0;}}
(2)windy数(SCOI2009)

黑幕以前的题,数位DP模板

链接在这http://www.lydsy.com/JudgeOnline/problem.php?id=1026

分析:按位枚举,最后叠加即可。注意要把位数不足的情况考虑进来

    这就是以前的省选题吧,可以为后世之模板

    不知道现在的题目以后是坟典或者是什么

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#define int long longusing namespace std;inline int read(){int i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(int x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}int f[15][10][2],sze,a,b,lim[15];int dp(int x){memset(f,0,sizeof(f));int tmp=x;sze=0;while(tmp){lim[++sze]=tmp%10;tmp/=10;}for(int i=0;i<=9;++i)if(i<=lim[1]) ++f[1][i][0];else ++f[1][i][1];for(int i=2;i<=sze;++i)for(int j=0;j<=9;++j)for(int k=0;k<=9;++k)if(abs(j-k)>=2){if(j<lim[i])f[i][j][0]+=f[i-1][k][1]+f[i-1][k][0];else if(j==lim[i]){f[i][j][0]+=f[i-1][k][0];f[i][j][1]+=f[i-1][k][1];}elsef[i][j][1]+=f[i-1][k][1]+f[i-1][k][0];}int ret=0;for(int i=1;i<lim[sze];++i)ret+=f[sze][i][1]+f[sze][i][0];ret+=f[sze][lim[sze]][0];for(int i=sze-1;i;--i)for(int j=1;j<=9;++j)ret+=f[i][j][1]+f[i][j][0];return ret;}signed main(){a=read();b=read();if(a!=1)write(dp(b)-dp(a-1));elsewrite(dp(b));return 0;}

终于到了今天讲的重点斜率优化

(3)玩具装箱(HNOI2008)

2008仿佛创造了很多奇迹与经典

题面http://www.lydsy.com/JudgeOnline/problem.php?id=1010

分析:唔其实黄学长写得挺详细的,有生之年我争取补上。

    要说的太多不知道从何说起

    最后还是无奈地甩链接http://hzwer.com/2114.html

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>using namespace std;inline long long read(){long long i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(long long x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}#define stan 55555long long f[stan],que[stan],length[stan],pre[stan],n,boldl;double slope(int x,int y){return (f[x]-f[y]+length[x]*length[x]-length[y]*length[y])*0.5/(length[x]-length[y]);}signed main(){n=read();boldl=read()+1;for(int i=1;i<=n;++i){length[i]=read();length[i]+=length[i-1]+1;pre[i]=length[i]-boldl;}int l=1,r=1;que[1]=0;for(int i=1;i<=n;++i){while(l<r&&slope(que[l],que[l+1])<=pre[i]) ++l;f[i]=f[que[l]]+(pre[i]-length[que[l]])*(pre[i]-length[que[l]]);while(l<r&&slope(que[r],i)<slope(que[r-1],que[r])) --r;que[++r]=i;}write(f[n]);return 0;}


(4)土地购买(USACO2008.Mar.)

2008的确创造了很多奇迹与经典...

题面...好像是权限

是这样,有n块长方形地(宽可以比长长),可以分成若干组买入,买入一组地的代价是该组地最长的长与最长的宽的乘积,求买n块地的最小代价

分析:这样,你其实可以通过一些预处理使其具有单调性

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>using namespace std;inline long long read(){long long i=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;}int buf[1024];inline void write(long long x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x){buf[++buf[0]]=x%10,x/=10;}while(buf[0]) putchar(buf[buf[0]--]+48);return ;}#define stan 55555struct field{long long l,w;}a[stan],land[stan];int n,tot,bound;long long f[stan],que[stan];bool cmp(field a,field b){if(a.l!=b.l) return a.l>b.l;else return a.w>b.w;}double slope(int x,int y){return (f[x]-f[y])*1.0/(land[y+1].l-land[x+1].l);}signed main(){n=read();for(int i=1;i<=n;++i){a[i].l=read();a[i].w=read();}sort(a+1,a+n+1,cmp);for(int i=1;i<=n;++i)if(a[i].w>bound){bound=a[i].w;land[++tot]=a[i];}int l=1,r=1;que[1]=0;for(int i=1;i<=tot;++i){while(l<r&&slope(que[l],que[l+1])<land[i].w) ++l;int j=que[l];f[i]=f[j]+land[j+1].l*land[i].w;while(l<r&&slope(que[r],i)<slope(que[r-1],que[r])) --r;que[++r]=i;}write(f[tot]);return 0;}
就这么样吧。

就让晴空如年轻时(虽然现在也还年轻),一样是蓝。

以后我会补分析的

抱歉