NOIP模拟赛
好像最近每天都会有模拟赛了.今天从高二逃考试跑到高一机房,然而高一也要考试,这回好像没有拒绝的理由了。
今天的模拟赛好像很有技术含量的感觉.
T1:xgy断句.
好诡异的题目,首先给出一些词,一个字符串,要求断句:每个句子至少有三个词,词数是总单词数的因数,单词得是字典里的词.求最多能断多少句.
首先当然是暴力匹配每一段是否是单词,然后$f_i$表示以$i$结尾的前缀中最多能断多少句,枚举断点进行转移,如何判断能否构成句子呢?搜索啊.
这里一定要注意如果最后一个状态是极小值,那么输出$0$.因为这个挂了$20$分.
1 # include <cstdio> 2 # include <iostream> 3 # include <cstring> 4 # include <string> 5 # include <algorithm> 6 # include <cmath> 7 # define R register int 8 # define ll long long 9 10 using namespace std; 11 12 const int maxn=102; 13 int n,len[maxn],l; 14 char dic[maxn][20]; 15 char s[300]; 16 int dp[300],leng,checkf; 17 int f[300][300],c[300][300]; 18 19 void dfs (int x,int s,int r) 20 { 21 if(x==r+1) 22 { 23 if(s>=3&&leng%s==0) checkf=1; 24 return ; 25 } 26 if(checkf) return; 27 for (R i=x;i<=r;++i) 28 if(c[x][i]) 29 dfs(i+1,s+1,r); 30 } 31 32 bool check (int l,int r) 33 { 34 if(f[l][r]!=-1) return f[l][r]; 35 leng=r-l+1; 36 checkf=false; 37 dfs(l,0,r); 38 f[l][r]=checkf; 39 return f[l][r]; 40 } 41 42 void init() 43 { 44 for (R i=1;i<=l;++i) 45 for (R j=1;j<=i;++j) 46 { 47 int f=false; 48 for (R k=1;k<=n;++k) 49 { 50 if(len[k]!=i-j+1) continue; 51 int ff=true; 52 for (R z=1;z<=len[k];++z) 53 if(s[j+z-1]!=dic[k][z]) ff=false; 54 if(ff) f=true; 55 if(f) break; 56 } 57 if(f) c[j][i]=1; 58 } 59 } 60 61 int main() 62 { 63 freopen("xgy.in","r",stdin); 64 freopen("xgy.out","w",stdout); 65 66 scanf("%d",&n); 67 memset(f,-1,sizeof(f)); 68 for (R i=1;i<=n;++i) 69 { 70 scanf("%s",dic[i]+1); 71 len[i]=strlen(dic[i]+1); 72 for (R j=1;j<=len[i];++j) 73 if(dic[i][j]>='A'&&dic[i][j]<='Z') dic[i][j]=dic[i][j]-'A'+'a'; 74 } 75 scanf("%s",s+1); 76 l=strlen(s+1); 77 for (R i=1;i<=l;++i) 78 if(s[i]>='A'&&s[i]<='Z') s[i]=s[i]-'A'+'a'; 79 init(); 80 for (R i=1;i<=l;++i) 81 dp[i]=-10000; 82 dp[0]=0; 83 for (R i=1;i<=l;++i) 84 for (R j=0;j<i;++j) 85 { 86 if(dp[j]==-10000) continue; 87 if(i-j+1>50) continue; 88 if(check(j+1,i)) dp[i]=max(dp[i],dp[j]+1); 89 } 90 printf("%d ",dp[l]); 91 fclose(stdin); 92 fclose(stdout); 93 return 0; 94 }
T2:多人背包.
显然前$k$优的状态不可能由比前$k$个还劣的状态转移过来,那么只保存前$k$优的即可.然而我强行把$KlogK$写成了$K^3$,竟然卡过了.
1 # include <cstdio> 2 # include <iostream> 3 # include <cstring> 4 # include <string> 5 # include <algorithm> 6 # include <cmath> 7 # define R register int 8 # define ll long long 9 10 using namespace std; 11 12 const int maxn=202; 13 int k,V,n; 14 int w[maxn],v[maxn]; 15 int dp[51][5001]; 16 int a[maxn]; 17 18 int main() 19 { 20 freopen("bag.in","r",stdin); 21 freopen("bag.out","w",stdout); 22 23 scanf("%d%d%d",&k,&V,&n); 24 for (R i=1;i<=n;++i) scanf("%d%d",&w[i],&v[i]); 25 memset(dp,128,sizeof(dp)); 26 dp[1][0]=0; 27 for (R i=1;i<=n;++i) 28 for (R j=V;j>=w[i];--j) 29 { 30 for (R z=1;z<=k;++z) 31 { 32 int T=dp[z][ j-w[i] ]+v[i]; 33 if(T<0) continue; 34 for (R l=z;l<=k;++l) 35 if(T>dp[l][j]) 36 { 37 for (R t=k;t>l;--t) 38 dp[t][j]=dp[t-1][j]; 39 dp[l][j]=T; 40 break; 41 } 42 } 43 } 44 int ans=0; 45 for (R i=1;i<=k;++i) ans+=dp[i][V]; 46 printf("%d",ans); 47 fclose(stdin); 48 fclose(stdout); 49 return 0; 50 }
T3:冰原探险.
似乎爆搜加$map$判重可过,离散化比较麻烦,而且把一些山之间的通道给离散没了...得了70.
1 # include <cstdio> 2 # include <iostream> 3 # include <map> 4 # include <algorithm> 5 # include <bitset> 6 # include <queue> 7 # define R register int 8 9 using namespace std; 10 11 const int dx[]={-1,0,0,1}; 12 const int dy[]={0,-1,1,0}; 13 const int maxn=4003; 14 const int knc=8003; 15 int n,N,M; 16 map <int,int> m; 17 int x[maxn],y[maxn],sx,sy,ex,ey,a[maxn],b[maxn],c[maxn],d[maxn]; 18 bool ic[knc][knc],vis[knc][knc]; 19 struct node 20 { 21 int x,y,v; 22 }; 23 queue <node> q; 24 25 int bfs () 26 { 27 node a,b; 28 a.x=sx,a.y=sy,a.v=0; 29 q.push(a); 30 while(q.size()) 31 { 32 a=q.front(); 33 q.pop(); 34 int x=a.x,y=a.y; 35 vis[x][y]=1; 36 if(a.x==ex&&a.y==ey) return a.v; 37 for (R d=0;d<4;++d) 38 { 39 x=a.x,y=a.y; 40 while(ic[x][y]==0) 41 { 42 x+=dx[d],y+=dy[d]; 43 if(x>N||y>M||x<1||y<1) break; 44 if(x==ex&&y==ey) 45 return a.v+1; 46 } 47 if(x>N||y>M||x<1||y<1) continue; 48 if(!ic[x][y]) continue; 49 x-=dx[d],y-=dy[d]; 50 if(vis[x][y]) continue; 51 vis[x][y]=1; 52 b.x=x,b.y=y,b.v=a.v+1; 53 q.push(b); 54 } 55 } 56 return 0; 57 } 58 59 int read () 60 { 61 R x=0,f=1; 62 char c=getchar(); 63 while(!isdigit(c)) { if(c=='-') f=-f; c=getchar(); } 64 while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar(); 65 return x*f; 66 } 67 68 int main() 69 { 70 freopen("ice.in","r",stdin); 71 freopen("ice.out","w",stdout); 72 73 n=read(); 74 sx=read(),sy=read(),ex=read(),ey=read(); 75 x[++x[0]]=sx,x[++x[0]]=ex; 76 y[++y[0]]=sy,y[++y[0]]=ey; 77 for (R i=1;i<=n;++i) 78 { 79 a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read(); 80 x[++x[0]]=a[i],x[++x[0]]=c[i]; 81 y[++y[0]]=b[i],y[++y[0]]=d[i]; 82 } 83 sort(x+1,x+1+x[0]); 84 sort(y+1,y+1+y[0]); 85 int cnt=0; 86 for (R i=1;i<=x[0];++i) 87 { 88 if(x[i]!=x[i-1]||i==1) cnt++; 89 m[ x[i] ]=cnt; 90 } 91 N=cnt; 92 for (R i=1;i<=n;++i) 93 a[i]=m[ a[i] ],c[i]=m[ c[i] ]; 94 sx=m[sx],ex=m[ex]; 95 cnt=0; 96 m.clear(); 97 for (R i=1;i<=y[0];++i) 98 { 99 if(y[i]!=y[i-1]||i==1) cnt++; 100 m[ y[i] ]=cnt; 101 } 102 M=cnt; 103 for (R i=1;i<=n;++i) 104 b[i]=m[ b[i] ],d[i]=m[ d[i] ]; 105 sy=m[sy],ey=m[ey]; 106 for (R i=1;i<=n;++i) 107 for (R j=a[i];j<=c[i];++j) 108 for (R z=b[i];z<=d[i];++z) 109 ic[j][z]=1; 110 111 printf("%d",bfs()); 112 fclose(stdin); 113 fclose(stdout); 114 return 0; 115 }
---shzr