6/14考试总结

实锤:我就是一个超级大垃圾!!!

必须从这个视角俯瞰自己了啊

T1:Censoring

FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过1e5的字符串S。他有一个包含n个单词的列表,列表里的n个单词记为ti,他希望从S中删除这些单词。
FJ每次在S中找到最早出现的列表中的单词(最早出现指该单词的开始位置最小),然后从S中删除这个单词。他重复这个操作直到S中没有列表里的单词为止。注意删除一个单词后可能会导致S中出现另一个列表中的单词
FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的
请帮助FJ完成这些操作并输出最后的S。第一行包含一个字符串S
第二行包含一个整数N N<2000
接下来的N行,每行包含一个字符串i???1??...tNt_Nt?N??。他希望从S中删除这些单词。
FJ每次在S中找到最早出现的列表中的单词(最早出现指该单词的开始位置最小),然后从S中删除这个单词。他重复这个操作直到S中没有列表里的单词为止。注意删除一个单词后可能会导致S中出现另一个列表中的单词
FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的
请帮助FJ完成这些操作并输出最后的S?5??的字符串S。他有一个包含n个单词的列表,列表里的n个单词记为t1t_1t?1??...tNt_Nt?N??。他希望从S中删除这些单词。
FJ每次在S中找到最早出现的列表中的单词(最早出现指该单词的开始位置最小),然后从S中删除这个单词。他重复这个操作直到S中没有列表里的单词为止。注意删除一个单词后可能会导致S中出现另一个列表中的单词
FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的
请帮助FJ完成这些操作并输出最后的S

一本通水题,AC自动机+栈,hash也能过,过多的回溯fail指针导致T,40。

AC自动机尝试匹配时需要通过fail指针进行回溯,所以在开始匹配前处理好结束标记就行。

利用好数组模拟栈的特性,不要一个一个pop。

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 char s[100005],word[100005];
 5 int n,cnt,last[100005],bj[100005],t[100005][26],fail[100005],fin[100005];
 6 int q[100005],q1,q2,leng,stack[100005],top;
 7 void insert(char *ss){
 8     int p=0,len=strlen(ss);
 9     for(int i=0;i<len;++i)
10         if(t[p][ss[i]-‘a‘])p=t[p][ss[i]-‘a‘];
11         else p=t[p][ss[i]-‘a‘]=++cnt;
12     fin[p]=len;
13 }
14 void bfs(){
15     q1=1;for(int i=0;i<=25;++i)if(t[0][i])q[++q2]=t[0][i];
16     for(;q1<=q2;++q1)for(int i=0;i<=25;++i)
17         if(t[q[q1]][i])fail[q[++q2]=t[q[q1]][i]]=t[fail[q[q1]]][i];
18         else t[q[q1]][i]=t[fail[q[q1]]][i];
19 }
20 void find(){
21     int p=0,k;
22     for(int i=0;i<leng;++i){
23         k=last[i]=p=t[p][s[i]-‘a‘];stack[++top]=i;
24         while(k){
25             if(fin[k]){
26                 p=last[stack[top-fin[k]+1]-1];
27                 for(int ii=1;ii<=fin[k];++ii)bj[stack[top]]=1,top--;
28                 break;
29             }
30             k=fail[k];
31         }
32     }
33 }
34 int main(){
35     //freopen("cen.in","r",stdin);
36     //freopen("cen.out","w",stdout);
37     scanf("%s%d",s,&n);leng=strlen(s);
38     for(int i=1;i<=n;++i)scanf("%s",word),insert(word);
39     bfs();find();
40     for(int i=0;i<leng;++i)if(!bj[i])putchar(s[i]);
41 }

考场错解

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 char s[100005],word[100005];
 5 int n,cnt,last[100005],bj[100005],t[100005][26],fail[100005],fin[100005];
 6 int q[100005],q1,q2,leng,stack[100005],top;
 7 void insert(char *ss){
 8     int p=0,len=strlen(ss);
 9     for(int i=0;i<len;++i)
10         if(t[p][ss[i]-‘a‘])p=t[p][ss[i]-‘a‘];
11         else p=t[p][ss[i]-‘a‘]=++cnt;
12     fin[p]=len;
13 }
14 void bfs(){
15     q1=1;for(int i=0;i<=25;++i)if(t[0][i])q[++q2]=t[0][i];
16     for(;q1<=q2;++q1)for(int i=0;i<=25;++i)
17         if(t[q[q1]][i])fail[q[++q2]=t[q[q1]][i]]=t[fail[q[q1]]][i];
18         else t[q[q1]][i]=t[fail[q[q1]]][i];
19 }
20 void find(){
21     int k=0;
22     for(int i=0;i<leng;++i){
23         k=last[i]=t[k][s[i]-‘a‘];stack[++top]=i;
24         if(fin[k]){
25             top-=fin[k];
26             k=last[stack[top]];
27
28         }
29     }
30 }
31 int main(){
32     scanf("%s%d",s,&n);leng=strlen(s);
33     for(int i=1;i<=n;++i)scanf("%s",word),insert(word);
34     bfs();find();
35     for(int i=1;i<=top;++i)putchar(s[stack[i]]);
36 }

考后正解(4次修改)

T2:记忆的轮廓

一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增,在[1,n]中,一共有n个节点。我们把编号在[1,n]的叫做正确节点,[n+1,m]的叫做错误节点。一个叶子,如果是正确节点则为正确叶子,否则称为错误叶子。莎缇拉要帮助昴到达贤者之塔,因此现在面临着存档位置设定的问题。
为了让昴成长为英雄,因此一共只有p次存档的机会,其中1和n必须存档。被莎缇拉设置为要存档的节点称为存档位置。当然不能让昴陷入死循环,所以存档只能在正确节点上进行,而且同一个节点不能存多次档。因为通往贤者之塔的路上有影响的瘴气,因此莎缇拉假设昴每次位于树上一个节点时,都会等概率选择一个儿子走下去。每当走到一个错误叶子时,再走一步就会读档。具体的,每次昴到达一个新的存档位置,存档点便会更新为这个位置(假如现在的存档点是i,现在走到了一个存档位置j>i,那么存档点便会更新为j)。读档的意思就是回到当前存档点。初始昴位于1,当昴走到正确节点n时,便结束了路程。莎缇拉想知道,最优情况下,昴结束路程的期望步数是多少?50<=p<=n<=700,m<=1500,T<=5。数据保证每个正确节点均有至少2个儿子,至多3个儿子。

全场爆零,数据范围没粘梯度,50%很好拿的也没人拿到,而我有看错了题目,0。

考场上其实已经想到了70%思路,但毕竟读错题了。

其中一种正解很抖机灵,存档点相距太远答案就会爆炸增长而存档机会又不少,设不会在相距40以上的点存档,就能把70变成AC

题解也有很多种,每种都值得学习。

 1 #include<cstdio>
 2 int n,m,p,ext[705],a,t,b;
 3 double times[705],dt[705][705],dp[705][705];
 4 inline double min(double a,double b){return a<b?a:b;}
 5 int main(){
 6     //freopen("memory.in","r",stdin);
 7     //freopen("memory.out","w",stdout);
 8     scanf("%d",&t);
 9     while(t--){
10         scanf("%d%d%d",&n,&m,&p);
11         for(int i=1;i<=n;++i)ext[i]=0;
12         for(int i=1;i<=m-n;++i){
13             scanf("%d%d",&a,&b);
14             if(a<=n)ext[a]++;
15             if(b<=n)ext[b]++;
16         }
17         for(int i=1;i<=n;++i)ext[i]++;
18         for(int i=2;i<=n;++i){
19             times[i]=1;
20             for(int j=i-1;j;--j)
21                 times[j]=times[j+1]*ext[j],dt[j][i]=dt[j+1][i]+times[j]/ext[j]+times[j]*2*(ext[j]-1)/ext[j];
22         }
23         for(int i=1;i<=700;++i)for(int j=1;j<=700;++j)dp[i][j]=1e10;
24         dp[1][1]=0;
25         for(int i=1;i<n;++i)for(int j=1;j<=i;++j)for(int k=i+1;k<=n;++k)dp[k][j+1]=min(dp[k][j+1],dp[i][j]+dt[i][k]);
26         printf("%.4lf",dp[n][p]);
27     }
28
29 }

考场错解

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 #define mm(a) memset(a,0,sizeof(a))
 5 int n,m,p,a,b,t;double dt[1505][1505],g[1505],tot[1505],dp[1505][1505];int fir[1505],to[1530],l[1530],cnt,s[1505];
 6 inline double min(double a,double b){return a<b?a:b;}
 7 void connect(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;}
 8 void dfs(int p){dt[p][p]=0;
 9     for(int i=fir[p];i;i=l[i]){
10         dfs(to[i]),s[p]++;
11         if(p>n)g[p]+=g[to[i]];
12     }
13     if(p>n)if(s[p])g[p]=g[p]/s[p]+1;else g[p]=1;
14     if(p<=n)for(int i=fir[p];i;i=l[i])tot[p]+=g[to[i]];
15 }
16 int main(){//freopen("1.in","r",stdin);
17     scanf("%d",&t);
18     while(t--){
19         scanf("%d%d%d",&n,&m,&p);
20         cnt=0;mm(tot);mm(g);mm(s);mm(fir);
21         for(int i=1;i<=n;++i)for(int ap=1;ap<=p;++ap)dp[i][ap]=1e20;dp[1][1]=0;
22         for(int i=1;i<=m-n;++i)
23             scanf("%d%d",&a,&b),connect(a,b);
24         for(int i=1;i<n;++i)connect(i,i+1);
25         dfs(1);
26         for(int i=1;i<=n;++i)
27             for(int j=i+1;j<=i+40&&j<=n;++j)
28                 dt[i][j]=dt[i][j-1]*s[j-1]+s[j-1]+tot[j-1];
29         for(int i=2;i<=n;++i)
30             for(int j=((i-40>=1)?i-40:1);j<i;++j)
31                 for(int ap=2;ap<=i;++ap)
32                     dp[i][ap]=min(dp[i][ap],dp[j][ap-1]+dt[j][i]);
33         printf("%.4lf\n",dp[n][p]);
34     }
35 }

考后正解(6次修改)

T3:雨天的尾巴

N个点,形成一个树状结构。有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成所有发放后,每个点存放最多的是哪种物品。

1<=N,M<=100000,1<=a,b,x,y<=N,1<=z<=1e9?9??

树上权值线段树动态开点+树上差分,考场上想出了树上差分可是不会弄,纯暴力50。

差分是从下往上,不是从根往下捯!这回彻底记住了。

改的时候线段树合并打错。。。忘了直接继承节点了而是此次都新建,M->R->M->R...

 1 #include<cstdio>
 2 #include<map>
 3 using namespace std;
 4 int f[5001][13],fir[5001],l[10001],to[10001],cnt,dep[10001],res;
 5 int ta[100001],tb[100001],tk[100001],lwb[5001],kind,a,b,LCA,n,mm;
 6 int have[5001][5001],ref[5001];
 7 map<int,int>m;
 8 void connect(int a,int b){
 9     l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;
10     l[++cnt]=fir[b];fir[b]=cnt;to[cnt]=a;
11 }
12 void dfs(int p){
13     for(int i=1;i<=12;++i)f[p][i]=f[f[p][i-1]][i-1];
14     for(int i=fir[p];i;i=l[i])if(to[i]!=f[p][0])f[to[i]][0]=p,dep[to[i]]=dep[p]+1,dfs(to[i]);
15 }
16 int lca(int a,int b){
17     if(dep[a]<dep[b])res=a,a=b,b=res;
18     for(int dt=dep[a]-dep[b];dt;dt-=dt&-dt)a=f[a][lwb[dt&-dt]];
19     if(a==b)return a;
20     for(int i=12;i>=0;--i)if(f[a][i]!=f[b][i])a=f[a][i],b=f[b][i];
21     return f[a][0];
22 }
23 int main(){
24     //freopen("tail.in","r",stdin);
25     //freopen("tail.out","w",stdout);
26     for(int i=0;i<=12;++i)lwb[1<<i]=i;
27     scanf("%d%d",&n,&mm);
28     for(int i=1;i<n;++i)scanf("%d%d",&a,&b),connect(a,b);
29     for(int i=1;i<=mm;++i){
30         scanf("%d%d%d",&ta[i],&tb[i],&tk[i]);
31         if(m.find(tk[i])==m.end())m[tk[i]]=++kind,ref[kind]=tk[i];
32         tk[i]=m[tk[i]];
33     }
34     dfs(1);
35     for(int i=1;i<=mm;++i){
36         LCA=lca(ta[i],tb[i]);
37         for(int ii=ta[i];ii!=LCA;ii=f[ii][0])have[ii][tk[i]]++;
38         for(int ii=tb[i];ii!=LCA;ii=f[ii][0])have[ii][tk[i]]++;
39         have[LCA][tk[i]]++;
40     }
41     for(int i=1;i<=n;++i){
42         int ans=0;
43         for(int j=1;j<=kind;++j)if(have[i][j]>have[i][ans]||(have[i][j]==have[i][ans]&&ref[j]<ref[ans]))ans=j;
44         printf("%d\n",ref[ans]);
45     }
46 }

考场错解

 1 #include<cstdio>
 2 #include<map>
 3 #include<algorithm>
 4 using namespace std;
 5 inline int max(int a,int b){return a>b?a:b;}
 6 int f[100001][19],fir[100001],l[200001],to[200001],cntt,dep[100001],res;
 7 int ta[100001],tb[100001],tk[100001],lwb[300001],kind,a,b,LCA,n,mm;
 8 int ref[100001],ans[100001];
 9 int w[15000000],lc[15000000],rc[15000000],cnt=100000;
10 int bf[100001];
11 map<int,int>m;
12 void connect(int a,int b){
13     l[++cntt]=fir[a];fir[a]=cntt;to[cntt]=b;
14     l[++cntt]=fir[b];fir[b]=cntt;to[cntt]=a;
15 }
16 void dfs(int p){
17     for(int i=1;i<=18;++i)f[p][i]=f[f[p][i-1]][i-1];
18     for(int i=fir[p];i;i=l[i])if(to[i]!=f[p][0])f[to[i]][0]=p,dep[to[i]]=dep[p]+1,dfs(to[i]);
19 }
20 int lca(int a,int b){
21     if(dep[a]<dep[b])res=a,a=b,b=res;
22     for(int dt=dep[a]-dep[b];dt;dt-=dt&-dt)a=f[a][lwb[dt&-dt]];
23     if(a==b)return a;
24     for(int i=18;i>=0;--i)if(f[a][i]!=f[b][i])a=f[a][i],b=f[b][i];
25     return f[a][0];
26 }
27 void add(int &p,int l,int r,int pos,int ww){
28     if(!p)p=++cnt;
29     if(l==r){w[p]+=ww;return;}
30     int mid=l+r>>1;
31     if(pos>mid)add(rc[p],mid+1,r,pos,ww);
32     else add(lc[p],l,mid,pos,ww);
33     w[p]=max((lc[p]?w[lc[p]]:0),(rc[p]?w[rc[p]]:0));
34 }
35 int find_ans(int p,int l,int r){
36     if(!w[p])return 0;
37     if(l==r)return l;
38     int mid=l+r>>1;
39     if(lc[p]&&w[p]==w[lc[p]])return find_ans(lc[p],l,mid);
40     else return find_ans(rc[p],mid+1,r);
41 }
42 void merge(int p,int l,int r,int &fa){
43     int mid=l+r>>1;if(!fa)fa=++cnt,printf("%d %d %d %d\n",p,l,r,cnt);
44     if(l==r){w[fa]+=w[p];return;}
45     if(lc[p])if(lc[fa])merge(lc[p],l,mid,lc[fa]);else lc[fa]=lc[p];
46     if(rc[p])if(rc[fa])merge(rc[p],mid+1,r,rc[fa]);else rc[fa]=rc[p];
47     w[fa]=max((lc[fa]?w[lc[fa]]:0),(rc[fa]?w[rc[fa]]:0));
48 }
49 void dfs_ans(int p){
50     for(int i=fir[p];i;i=l[i])if(to[i]!=f[p][0])dfs_ans(to[i]);
51     ans[p]=find_ans(p,1,kind);if(f[p][0])merge(p,1,kind,f[p][0]);
52 }
53 int main(){
54     for(int i=0;i<=18;++i)lwb[1<<i]=i;
55     scanf("%d%d",&n,&mm);
56     for(int i=1;i<n;++i)scanf("%d%d",&a,&b),connect(a,b);
57     for(int i=1;i<=mm;++i)scanf("%d%d%d",&ta[i],&tb[i],&tk[i]),bf[i]=tk[i];
58     sort(bf+1,bf+1+mm);
59     for(int i=1;i<=mm;++i)if(m.find(bf[i])==m.end())m[bf[i]]=++kind,ref[kind]=bf[i];
60     for(int i=1;i<=mm;++i)tk[i]=m[tk[i]];
61     dfs(1);
62     for(int i=1;i<=mm;++i){
63         LCA=lca(ta[i],tb[i]);
64         add(ta[i],1,kind,tk[i],1);add(tb[i],1,kind,tk[i],1);
65         add(LCA,1,kind,tk[i],-1);add(f[LCA][0],1,kind,tk[i],-1);
66     }
67     dfs_ans(1);
68     for(int i=1;i<=n;++i)printf("%d\n",ref[ans[i]]);
69 }

考后正解(23次修改)

你很弱诶,你真的很弱诶。啥都不会打,暴力骗分总分还干不过T1一个hash。

考场上心态太自信了吧,T1打完过样例之后又手模了4,5组都没问题。就往后走了

T2,T3寻思着T1应该稳了,100分rank也不低就飘了。

平时打代码要注重理解。。。不要着急赶进度,注重积累,记住每一个小知识点,谁知道什么时候会有用

难题可以不打,简单题必须AC,暴力对拍检查低错,先稳后强。

加油吧,还有机会,小心被干到第二机房。

原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11057937.html

时间: 2024-07-29 19:33:46

6/14考试总结的相关文章

日常:6.14——考试苟过记

我苟了考试,我不是人 第一题苟过去了…… 第三题打爆了. 打了个lca想骗点分,期望得分40,但是我建的树里面有一半的节点死活找不着父节点…… 调了俩小时,另外一个小时用来苟第一题. 我好虚啊 谁能告诉我为什么在bfs里面输出的都是完美的爸爸 到外面就成零了! 我是不是杀了人家的父亲 警察叔叔……我是好人……我没杀人……我杀的是节点…… 手模一个:(/起了歹念 还是要继续努力啊! 原文地址:https://www.cnblogs.com/xingmi-weiyouni/p/11025099.ht

From 7.8 To 7.14

From 7.8 To 7.14 大纲 学科 英语的话每天早上背单词, 争取每天做一篇完型, 一篇阅读, 一篇短文填空, 一篇改错, 一篇七选五??? 似乎太多了, 先试一下吧 语文的话, 尝试翻译一下文言文??? 理科先不管他 竞赛 考试, 题解, 做题, 恩, 应该差不多吧 7.12 考试, 改题... 今天做的题目有:做了个球 恩, 就推了几个斯特林数的式子, 硬是写了半个下午加一个晚上, 我晕死 7.13 早上按时背了英语, 然后发现之前有好多背了的单词不记得了, 可能是没有复习吧...

cisco learn book index

------------------------------------------------------------------ Routing TCP/IP Volume 1 , Second Edition ------------------------------------------------------------------ Routing TCP/IP Volume 2 ---------------------------------------------------

2016年10月总结

一.工作 一个月的时间里,西宁占90%,昆明10%. 本月情况: 西宁 整个月的重心都在西宁上,一个星期改一次研发计划,并且经常不按时间节点发版,测试没办法按照计划来执行,真的是好累--觉得自己应该多去协助研发,但是估计是自己能力有限,所以基本只能抛出问题,只能在需求有疑问的时候给出解决方案,然后就是测试出问题的时候给出解决建议. 我个人这边的主要工作,就是青海对接这边的测试了. A 感觉不好的地方: 研发和项目经理沟通方案和确定方案.计划的时候,都没有通知测试,待全部完成后才通知我们,导致我们

全国计算机等级考试二级教程-C语言程序设计_第14章_结构体、共用体和用户定义类型

例14.2 对比向函数传递结构体数组名和向函数传递结构体变量名的区别. 1 #include<stdio.h> 2 3 typedef struct 4 { 5 int num; 6 double mark; 7 }REC; 8 9 void sub1(REC x) 10 { 11 x.num = 23; 12 x.mark = 81.5; 13 } 14 15 void sub2(REC y[]) 16 { 17 y[0].num = 12; 18 y[0].mark = 77.5; 19

喵哈哈村的魔法考试 Round #14 (Div.2)

喵哈哈村的四月半活动(一)(水题) 描述 今天是四月十五日,是喵哈哈村一年一度的四月半活动,这次活动是由今日头条赞助. 今日头条的乐乐同学在广场上出了一道题,谁答对,就能获得他的祝福哦. 题目如下: 勾股定理是初中数学的重要定理.它的内容是:直角三角形中,两直角边长度的平方和等于斜边长度的平方.若边c是斜边,边a和b是直角边,则a×a+b×b=c×c. 已知一个直角三角形的两边长,求第三条边的长度. 输入 只有一行,这一行有两个用空格隔开的正整数,即已知的两条边. 100%的数据,给出的边长大于

安徽科技学院2014-2015-1学期计算机14级12班《C语言程序设计I》期末考试

1274 Problem A 十字架 Time Limit:1000MS  Memory Limit:65536K Total Submit:5 Accepted:4 Description 现在给你一个7*7的正方形,让你来数一数这个正方形中有多少的十字架.一个十字形为一个十字架,多个个十字架可以相连. 例如:1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 0 1 0 0 1 0 1 0 1 0 0 1 0 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 1 1

OCP认证考试之052最新题库及答案整理-第14题

14.Which command is used to display files that no longer conform to the backup retention policy? A) REPORT OBSOLETE B) SHOW DATAFILE BACKUP COPIES C) CROSSCHECK BACKUP D) LIST EXPIRED BACKUP Answer:A 原文地址:http://blog.51cto.com/13854012/2145302

【OCP-12c】CUUG 071题库考试原题及答案解析(14)

14.(6-13) choose the best answer:View the Exhibit and examine the structure of the ORDERS table.Which UPDATE statement is valid? A) UPDATE ordersSET order_date = '12-mar-2007'AND order_total = TO_NUMBER(NULL)WHERE order_id = 2455; B) UPDATE ordersSET