9.5联合作战战果

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
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mod 10007
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 ;
}
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>=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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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 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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define eps 1e-7
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 ;
}
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]
4.动态规划部

(1)装箱问题(luoguP1049)

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

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

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

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define int long long
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 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

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

(3)玩具装箱(HNOI2008)

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

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

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

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

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

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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 55555
long 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


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

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

题面...好像是权限

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

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

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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 55555
struct 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
就这么样吧。

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

以后我会补分析的

抱歉

你可能感兴趣的:(OI,字符串算法纲,动态规划纲)