NOIP模拟赛-2018.11.5

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 }
xgy断句

  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

原文地址:https://www.cnblogs.com/shzr/p/9919122.html