题目

【GDKOI2003】最大公共子串

【题目描述】
从一个给定的串中删去(不一定连续地删去)0个或0个以上的字符,剩下的字符按原来的顺序组成的串是该串的字串。例如:“”, “a”, “aaa”,“bbb”,“xabb”,“xaaabbb”都是串“xaaabbb”的字串。(例子中的串不包括引号)
编程求N个非空串的最长公共子串的长度。
限制:2<=N<=100:N个串中的字符只会是数字0,1,…,9或小写字母a,b,…,z;每个串非空且最多含100个字符;N个串的长度的乘积不会超过30000。
【输入】
文件第一行是一个整数T,表示测试数据的个数(1<=T<=10)。接下来T组测试数据。各族测试数据的第一行是一个整数Ni,表示第i数据中串的个数。各组测试数据的第2到N+1行中,每行一个串,串中不会有空格,但行首和行未可能有空格,这些空格当然不算作串的一部分。
【输出】
输出T行,每行一个数,第I行的数表示第I组测试数据中Ni的非空串的最长公共子串的长度
【样例输入】
1
3
ab
bc
cd
【样例输入】
0


【GDKOI2003】分球

【题目描述】
在一个装满财宝的屋子里,有2N个盒子排成一排。除了两个相邻的空盒外,其余的每个盒子里都装有一个金球或者一个银球,总共有N-1个金球和N-1个银球。以下是一个N=5时的例子,G表示金球,S表示银球:

任意两个相邻的非空的盒子里的球可以移动到两个相邻的空盒中,移动不能改变这两个球的排列顺序。写一个程序,用最少的移动次数把所有的金球都移到所有银球的左边。
【输入】
输入文件包含多组数据。第一行为K,表示数据的总数。
每组数据的第一行是N(3<=N<=7),第二行是2N个盒子的初始状态。金球用a表示,银球用b表示,空盒用空格表示。每两组相邻数据用空行隔开。
【输出】
对于每一组数据,若无解则输出一行-1,若有解,输出最少移动次数,相邻的两组数据用一个空行隔开。
【输入】
3
3
abab

5
abba abab

6
a babbababa
【输出】
-1

3

4
【数据范围限制】
k<5


【GDKOI2004】使命的召唤

【题目描述】
你玩过call of duty这个游戏吗?这个游戏以诺曼底登陆为背景,假设你是盟军的一员,身在前线去完成许多任务而粉碎纳粹的野心。现在假设有一个任务,德军有很多机枪阵地,火力很猛,如果不把它们摧毁就会对盟军的推进造成很大损失,盟军打算派出一些敢死队员深入阵地把这些机枪阵地炸毁,当然,敢死队员会有很大的生命危险,所以盟军的指挥官希望你能帮他把损失降到最少。
【输入】
输入数据第一行是一个整数n(1<=n<=200),代表有多少个机枪阵地需要摧毁。然后接下来n行,每行两个整数xi,yi,代表每个机枪阵地的坐标(0<=xi,yi<=30000),然后接着一个整数m,跟着有m行,每行两个整数p和q(1<=p,q<=n,p<>q),代表机枪阵地p和机枪阵地q之间有路相连,敢死队员炸掉一个机枪阵地之后,必须从当前的机枪阵地出发沿着路到达下一个x坐标比当前阵地大的阵地(因为机枪阵地的纵深方向是沿着x坐标递增方向的),如果不存在这样的阵地,那这名敢死队员就完成任务了。简单来说,一个敢死队员可以空降到任意一个机枪阵地(设为a0),然后从这个阵地出发按照上面所述可以摧毁一系列机枪阵地(顺序列为a0,a1,a2...ak),而这一系列机枪阵地的x坐标满足(x0 < x1 < x2 < ... < xk)。从安全和效率出发,每个敢死队员可以带任意个炸弹。任意两个敢死队员的路线不能有交点。现在问你怎么安排敢死队员的路线,可以使到用最小数目的敢死队员去完成这个艰巨的任务。
【输出】
输出一个整数,就是所求的敢死队员的最小数目。
【样例输入】
4
25990 5850
8263 2957
1067 22231
4109 4577
3
4 1
2 4
1 3
【样例输出】
2
【样例解释】
上面的例子最少需2个敢死队员,1种方案是:1个摧毁阵地4后再去摧毁阵地2,1个敢死队员摧毁阵地3后去摧毁阵地1。
【数据范围限制】
m<10000


过程

这次比赛似乎没有那么难了(某一次比赛,三道题的算法都是我没有学过的毒瘤算法

第一题

比赛时没有看出是什么东东,发现它可以随便地删除字符,但暴搜明显爆炸(串的长度最长有100)。想到hash,但不知道怎么搞,于是果断放弃。

第二题

这题看起来很可做,但无论我怎么模拟样例都过不了。
自尊心大大受创,遂弃疗。

后来想完第三题,我又折回来做第二题,发现可以用双向BFS+哈希暴力做。
于是便打起了代码,但最后只拿到了87.5分。

第三题

这题看上去很像一道二分图最大匹配。但是看到“任意两个敢死队员的路线不能有交点”时,我懵逼了——这不是计算几何吗?!怎么算两条线段间有没有交点啊?!我不会呀!
但我不愿放弃,于是又想了一会儿。。。
发现题目没有说敢死队员要怎么走,也就是说两条路径相交时,敢死队员会绕开:

这样似乎就解决了问题,但是我却没有在题目里面发现这样的字样,遂弃疗。
后来打了个表,12.5分。

总分

0+87.5+12.5=100


题解

T1

方法一:DP(正解)

设\(f_{x_1,x_2,x_3,...,x_n}\)表示第1个字符串在前\(x_1\)个字符中取子串,第2个字符串在前\(x_2\)个字符中取子串……第i个字符串在前\(x_i\)个字符中取子串。
那么就可以列出状态转移方程:
\[ f_{x_1,x_2,x_3,...,x_n}=\begin{cases} 0, & \text{if $x_i=0\space (i=1,2,3,...,n)$}\\ f_{x_1-1,x_2-1,x_3-1,...,x_n-1}+1, & \text{else if $s_{i,x_i}=s_{1,x_1}\space (i=2,3,...,n)$}\\ \max(f_{x_1-1,x_2,x_3,...,x_n},f_{x_1,x_2-1,x_3,...,x_n},...,f_{x_1,x_2,x_3,...,x_n-1})&\text{else} \end{cases} \]
但是这样DP,数组要开到\(10^{200}\)那么大,明显爆炸。
这时我们就要用另一种开数组的方法了。
再看一下题目,发现了这句话:“N个串的长度的乘积不会超过30000”
因此,我们只用开DP数组\(f[0..30000]\),其中原来\(f_{x_1,x_2,x_3,...,x_n}\)的指改为储存在\(f_{(x_1-1)+(x_2-1)*|S_1|+(x_3-1)*|S_1|*|S_2|+...+(x_n-1)*|S_1|*|S_2|*...*|S_{n-1}\space|}\)中。
这里可以用dfs实现。

方法二:分类讨论(水法)

其实我们完全可以在最短串中暴力搞出一个子串,然后逐个串判断。
其中(设S为极限情况下的输入的最短串)
①当\(n=1\)时
\(|S|=30000\)
这样枚举明显爆炸。
但是这时的答案明显为\(|S|\),直接输出即可。
②当\(n=2\)时
\(|S|\approx \sqrt{30000}\approx 173\)
这样还是会炸。
这时,我们可以弄一个2维DP,搞一搞就可以了。
③当\(n=3\)时
\(|S|\approx \sqrt[3]{30000}\approx 31\)
似乎会炸,于是再搞一个3维DP。
④当\(n=4\)时
\(|S|\approx \sqrt[4]{30000}\approx 13\)
这时就不会再炸了。因此当\(n\geq 4\)时可以直接用暴力做。

方法三:hash

实话说这方法麻烦得很,我也不太会,这里就不加阐述了。
据说此题还可以用后缀自动机?!

T2

这题明显是暴搜,但我担心时间会炸,于是打了个双向BFS。
起点的初始状态就是输入的那个,而终点的状态就是所有金球在左,银球在右的状态(枚举空格)。
可以设空格为0,金球为1,银球为2,压一下状态,然后用哈希判重。
这里的哈希值取得要好,既要是状态总数的2~3倍,也要不那么大(以免爆空间)。由于空间开得挺大的(128000KB),因此我用了11454637。
这题应该是所有题目中最水的,然而我比赛时却只拿了87.5分。
后来找了半天,发现是读入出了问题:
我本想用scanf("\n");把回车给弄掉,结果却莫名其妙地把行首空格也处理掉了。后来改用getchar();就对了。
注意:这题输出时行与行之间不要有空行,不然会WA

T3

这题果然是二分图最大匹配,和我想的一模一样(敢死队员可以绕过去)。
看来想问题有事不能想太多呀!
因为队员们的路线不能有交点,又要走到每一个机枪阵地,因此我们可以推断出一个结论:每一个机枪阵地最多只能从一个机枪阵地走过来。因此我们只要计算最少有多少个机枪阵地不可以从别的机枪阵地走来就可以了。
我们可以新建一个源点S,从它连接n条边到n个机枪阵地。再把所有的机枪阵地克隆一份到右边(第i个点克隆后成为第i+n个点),若是能从阵地x走到阵地y,那么就在点x和点y+n间连一条边。最后在从所有的右边的点连边到汇点T。
其中,所有的边的流量都为1。
当然,这题也可以用匈牙利算法来做。
最后输出n-最大匹配数即可。


标程

T1

#include<cstdio>
#include<cstring>
using namespace std;
#define M 30005
#define N 105
int n,len[N],f[M],x[N];
char s[N][N];
inline int max(int x,int y){return x>y?x:y;}
int dp()
{int i,j,index=x[n]-1;if(x[n]==0) return 0;for(i=n-1;i>0;i--){if(x[i]==0) return 0;index=index*len[i]+x[i]-1;}if(f[index]>=0) return f[index];for(i=2;i<=n;i++){if(s[1][x[1]]!=s[i][x[i]]){for(j=1;j<=n;j++){x[j]--;f[index]=max(f[index],dp());x[j]++;}return f[index];}}for(i=1;i<=n;i++) x[i]--;j=dp()+1;for(i=1;i<=n;i++) x[i]++;return f[index]=j;
}
int main()
{int tt,i,j;scanf("%d",&tt);while(tt--){memset(f,-1,sizeof(f));scanf("%d\n",&n);for(i=1;i<=n;i++){scanf("%s",s[i]+1);x[i]=len[i]=strlen(s[i]+1);}printf("%d\n",dp());}return 0;
}

T2

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define mod 11454637
struct node
{int now,step;
};
int hasha[mod+10],hashb[mod+10],input[20],n,step;
queue<node>a;
queue<node>b;
void swap(int &x,int &y){int z=x;x=y;y=z;}
bool finda(int k,bool b)
{int x=k%mod+1;while(hasha[x]&&hasha[x]!=k) x=(x+1)%mod+1;if(hasha[x]==k) return 1;if(b) hasha[x]=k;return 0;
}
bool findb(int k,bool b)
{int x=k%mod+1;while(hashb[x]&&hashb[x]!=k) x=(x+1)%mod+1;if(hashb[x]==k) return 1;if(b) hashb[x]=k;return 0;
}
int bfsa()
{node u;int i,j,k,t,num[20];while((!a.empty())&&(a.front()).step==step){u=a.front();a.pop();k=u.now,i=j=0;while(i<n){num[++i]=k%3;if(num[i]==0&&j==0) j=i;k/=3;}for(i=1;i<n;i++) if(i!=j&&i!=j-1&&i!=j+1){swap(num[i],num[j]);swap(num[i+1],num[j+1]);for(k=n,t=0;k>0;k--) t=t*3+num[k];if(!finda(t,1)){if(findb(t,0)) return step*2+1;a.push((node){t,step+1});}swap(num[i],num[j]);swap(num[i+1],num[j+1]);}}return 0;
}
int bfsb()
{node u;int i,j,k,t,num[20];while((!b.empty())&&(b.front()).step==step){u=b.front();b.pop();k=u.now,i=j=0;while(i<n){num[++i]=k%3;if(num[i]==0&&j==0) j=i;k/=3;}for(i=1;i<n;i++) if(i!=j&&i!=j-1&&i!=j+1){swap(num[i],num[j]);swap(num[i+1],num[j+1]);for(k=n,t=0;k>0;k--) t=t*3+num[k];if(!findb(t,1)){if(finda(t,0)) return step*2+2;b.push((node){t,step+1});}swap(num[i],num[j]);swap(num[i+1],num[j+1]);}}return 0;
}
int main()
{int tt,i,j,k,t;char ch;bool bk;scanf("%d\n",&tt);while(tt--){memset(hasha,0,sizeof(hasha));memset(hashb,0,sizeof(hashb));while(!a.empty()) a.pop();while(!b.empty()) b.pop();scanf("%d",&n);i=k=step=0;getchar();while(ch=getchar(),ch==' '||ch=='a'||ch=='b'){if(ch==' ') input[++i]=0;else input[++i]=ch-'a'+1;}n<<=1;for(j=n;j>0;j--) k=k*3+input[j];i=finda(k,1);a.push((node){k,0});bk=0;for(i=1;i<n;i++){k=t=0;for(j=n;j>0;j--){if(j!=i&&j!=i+1){t++;if(t<n/2) k=k*3+2;else k=k*3+1;}else k*=3;}t=findb(k,1);b.push((node){k,0});if(finda(k,0)) bk=1;}if(bk) puts("0");else{while((!a.empty())&&(!b.empty())){i=bfsa();if(i>0) break;i=bfsb();if(i>0) break;step++;}if(i>0) printf("%d",i);else printf("-1");if(tt>0) printf("\n");}}return 0;
}

T3

#include<cstdio>
using namespace std;
#define M 40405
#define N 405
#define S 401
#define T 402
struct edge
{int start,end,lenth,next;
}a[M];
int x[N],first[N],dis[N],GAP[N],n,s=1;
inline int mymin(int x,int y){return x<y?x:y;}
void inc(int x,int y)
{a[++s]=(edge){x,y,1,first[x]};first[x]=s;a[++s]=(edge){y,x,0,first[y]};first[y]=s;
}
int sap(int k,int flow)
{if(k==T) return flow;int have=0,i,now;for(i=first[k];i;i=a[i].next){if(dis[a[i].start]==dis[a[i].end]+1&&a[i].lenth){now=sap(a[i].end,mymin(a[i].lenth,flow-have));a[i].lenth-=now,a[i^1].lenth+=now,have+=now;if(flow==have) return have;}}if((--GAP[dis[k]])==0) dis[S]=n;++GAP[++dis[k]];return have;
}
int main()
{int m,i,j,u,v,ans=0;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d%d",&x[i],&j);inc(S,i),inc(i+n,T);}scanf("%d",&m);for(i=1;i<=m;i++){scanf("%d%d",&u,&v);if(x[v]>x[u]) inc(u,v+n);if(x[u]>x[v]) inc(v,u+n);}while(dis[S]<n) ans+=sap(S,N);printf("%d\n",n-ans);return 0;
}

转载于:https://www.cnblogs.com/huangzihaoal/p/11154480.html

2018.07.17【省赛模拟】模拟B组 比赛总结相关推荐

  1. 2018.07.17【省赛模拟】模拟B组 比赛题解(总结)

    今天一看排名,what the,又垫底了,新初二第一YYT287.5,第二WYD120 T1: 最大公共子串 分类讨论+DP 题目描述 从一个给定的串中删去(不一定连续地删去)0个或0个以上的字符,剩 ...

  2. 2018.07.17 洛谷P1368 工艺(最小表示法)

    传送门 好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现. 首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头 ...

  3. 2018 蓝桥杯省赛 B 组模拟赛(一)--封印之门

    题目链接:https://nanti.jisuanke.com/t/A1594 蒜头君被暗黑军团包围在一座岛上,所有通往近卫军团的路都有暗黑军团把手.幸运的是,小岛上有一扇上古之神打造的封印之门,可以 ...

  4. 蓝桥杯 Java B组 省赛决赛模拟赛 详解及小结汇总+题目下载【2013年(第4届)~2021年(第12届)】

    蓝桥杯 Java B组 省赛决赛模拟赛 详解及小结汇总+题目下载[2013年(第4届)~2021年(第12届)] 百度网盘-CSDN蓝桥杯资料(真题PDF+其它资料)   提取码:6666 2013年 ...

  5. 2018年河北单招计算机试题,2018年河北单招英语模拟试题一【含答案】.doc

    2018年河北单招英语模拟试题一[含答案].doc (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 7.9 积分 2018年河北单招英语模拟试题一[ ...

  6. 2021.03.30【2021省赛】模拟 比赛总结

    2021.03.30[2021省赛]模拟 比赛总结 地址: https://gmoj.net/senior/#contest/home/3350 T1: 神奇纸牌(uno) T2: 凌乱平衡树 (tr ...

  7. 第十三届蓝桥杯模拟赛第二期JAVA组个人题解

    第十三届蓝桥杯模拟赛第二期JAVA组个人题解 文章目录 第十三届蓝桥杯模拟赛第二期JAVA组个人题解 题目1 题目2 题目3 题目4 题目5 题目6 题目7 题目8 题目9 题目10 题目1 小蓝的I ...

  8. 第十四届蓝桥杯第三期模拟赛 C/C++ B组 原题与详解

    本篇文章对第十四届蓝桥杯第三期模拟赛所有的题目进行了详细解析.如果大家还想刷题的话,我给大家整理出了第十二届的省赛真题:第十二届省赛C/C++ B组真题.推荐大家可以去做一下. 文章目录 一.填空题 ...

  9. 2021.08.09【普及组】模拟赛C组比赛总结

    文章目录 2021.08.09[普及组]模拟赛C组比赛总结 写在前面: T1 :[普及模拟]生产武器 题目大意: 正解: T2 :[普及模拟]城市连接 题目大意: 正解: T3 :[普及模拟]抢救文件 ...

最新文章

  1. 零起点学算法22——华氏摄氏温度转换
  2. 算法--------二叉树的中序遍历
  3. (003)RN开发VSCode配置RN以及常用快捷键
  4. matlab学习日记,MATLAB学习笔记---DAY1
  5. 自己写编译器学习总结
  6. 微信公众号自动回复 node
  7. guava限流器RateLimiter原理及源码分析
  8. 为Raspberry Pi开发.NET应用程序:第2部分
  9. Druid monitor中SQL监控显示不出数据(已解决)
  10. 【数学模型】基于Matlab模拟超市排队系统
  11. 友情链接SEO工具检测不出来
  12. 2022陕西省安全员B证操作证考试题库及模拟考试
  13. 他,1年9个月获清华博士学位,一作身份发27篇SCI,组队击败NASA打破“航天奥林匹克”欧美垄断...
  14. Switch游戏机Type-C底座方案
  15. 用标准遗传算法求函数最大值
  16. 【学习笔记】【算法】【智能优化】粒子群优化(PSO)
  17. 树莓派作品2_莫尔斯电码
  18. influxdb查看数据库命令_02-命令行操作influx
  19. 基于QT的界面框架qcanpool使用教程(废弃)
  20. 企业拜访调查问卷计算机,1-1计算机应专业行业及企业调查问卷模板.doc

热门文章

  1. App绕过SSL Pinning机制抓取Https请求
  2. 如何理解云安全态势管理(CSPM)
  3. 我的创作纪念日(2021.7.18 - 2022.7.18)
  4. 湖南大学计算机学院陈浩,陈浩(湖南大学信息科学与工程学院教授)_百度百科...
  5. 自然语言处理NLP快速入门
  6. 网络安全的重要性及应对策略
  7. Elasticsearch分页解决方案研究
  8. 花店管理java_JAVA基于B/S模式下的在线花店
  9. 5.3使用凯撒密码加密和解密英文文件python
  10. linux系统dm数据库安装