Word rings

题目描述

这道题就是想求出所有的环,然后在所有环中比较出环串的平均长度最长的那一个,然后就输出平均长度最长的,如果在一个点当中的样例中没有环的话我们就应该输出“No Sulution.”


- 注意是No Sulution. 有句点,题目的翻译有一点问题在测试中数据有句点,在原文中也有句点


首先我们的思路应该是跑最长路,因为无论我们想求平均长度最长,我们肯定希望每一个都非常长,刚好边权为字符串长度,那么跑一下当正环出来之后就跑不出来了。但是这题数据太大了我们过不了

当我们首先用枚举环来求出答案士失败时那么我们接下来的思路应该是尝试枚举答案,然后求出是否有满足答案的环,但若我们此时枚举的答案为ans,有k个字符串,那么就有了这样一个式子ans∗k=len1+len2+len3+...+lenkans∗k=len1+len2+len3+...+lenk

在我们得到那道这个式子之后,我们对它进行必要的移项

len1−ans+len2−ans+len3−ans+...+lenk−ans=0

所以说我们可以得到对于满足以下式子,也可以判断是否是正环

0≤len1−ans+len2−ans+len3−ans+...+lenk−ans0

那么对于这个ans值,ans值越大,那么存在正环的概率也就越小,当ans值越小时,ans大的情况肯定也会包含在里面,这就保证了单调性,我们在确定这个方法的单调性之后我们就可以直接使用二分答案来做这道题了。

对于最长路的求解我们应该使用Dijkstra对此进行判断正环(因为Dijkstra不能处理负数情况,时间的复杂度比较低),但是我们也可以用SPFA来判正环(我们可以将每一条边的权值乘以负一),然后我们再加一个spfa优化就可以了。

补充

在这里讲一下如何进行缩点,在题目中我们不难发现对于一串字符串来说只有首尾的各两个数字是有用的,其他的字符我们可以忽略不计,但是我们学要用一下哈希来使我们的aa到zz中间的所有的字符不会冲突,(第一位可以乘以26,第二位用1到25表示,那么我们得到的那个数整除26的和然后再+1就代表第一个字符在a到z中的第几个位置,之后我们可以再用那个数模26然后再+1就代表第二个字符在a到z中的第几个位置)这样可以保证不会出现冲突了。

直接把一个字符串当中的首尾各两个字符变为两个点整个字符串的长度为我们的边权建立一条边这样就可以进行建边了,再执行之前的工作就可以work it out(解决)了

好题推荐

(spfa的优化的题目)

这些题可以帮助大家练习好spfa的优化的题目

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=100005;
  4. const double eps=1e-6;
  5. int n;
  6. char s[1005];
  7. int ord(char a,char b) {//缩点(避免冲突)
  8. return (a-'a')*26+b-'a';
  9. }
  10. int lnk[N],ne[N],la[N],co[N],tot;
  11. double dis[N];
  12. bool vis[N];
  13. void add(int x,int y,int z) {
  14. ne[++tot]=y;
  15. co[tot]=z;
  16. la[tot]=lnk[x];
  17. lnk[x]=tot;
  18. }
  19. bool dfs(int x,double v) {//dfs版的spfa
  20. vis[x]=1;
  21. for(int j=lnk[x]; j; j=la[j]) {
  22. if(dis[ne[j]]<dis[x]+co[j]-v) {
  23. dis[ne[j]]=dis[x]+co[j]-v;
  24. if(vis[ne[j]])return 1;
  25. else {
  26. if(dfs(ne[j],v))return 1;
  27. }
  28. }
  29. }
  30. vis[x]=0;
  31. return 0;
  32. }
  33. bool check(double mid) {//判断是否是负环
  34. memset(vis,0,sizeof(vis));
  35. memset(dis,0,sizeof(dis));
  36. for(int i=0; i<=5000; ++i)
  37. if(dfs(i,mid))return 1;
  38. return 0;
  39. }
  40. int main() {
  41. while(cin>>n) {
  42. memset(lnk,0,sizeof(lnk));
  43. tot=0;
  44. if(n==0){
  45. return 0;
  46. }
  47. for(int i=1; i<=n; ++i) {
  48. scanf("%s",s+1);
  49. int l=strlen(s+1);
  50. add(ord(s[1],s[2]),ord(s[l-1],s[l]),l);
  51. }
  52. double l=0,r=1005;
  53. while(r-l>eps) {//进行二分答案求解
  54. double mid=(l+r)/2;
  55. if(check(mid))l=mid;
  56. else r=mid;
  57. }
  58. if(l==0)cout<<"No solution."<<endl;
  59. else cout<<l<<endl;
  60. }
  61. }

Word rings的更多相关文章

  1. 【POJ2949】Word Rings(最大平均值环)

    题意:给定N个字符串,如果A串的最后两个字母跟B串的前两个字母相同它们就能连接. 求一个由字符串组成的首尾相连的环,使(字符串总长度/字符串个数)最大. n<=100000 len<=10 ...

  2. 【转】最短路&差分约束题集

    转自:http://blog.csdn.net/shahdza/article/details/7779273 最短路 [HDU] 1548 A strange lift基础最短路(或bfs)★254 ...

  3. ACM一些题目

    Low Power 先二分答案,可以通过调整证明同一台机器选的两个芯片必然是提供能量数值相邻的两个.所以再贪心一下就可以了. 时间复杂度\(O(n \log n)\). Factors 假设\(k\) ...

  4. loj题目总览

    --DavidJing提供技术支持 现将今年7月份之前必须刷完的题目列举 完成度[23/34] [178/250] 第 1 章 贪心算法 √ [11/11] #10000 「一本通 1.1 例 1」活 ...

  5. 2019寒假练题计划——LibreOJ刷题计划 &《信息学奥赛一本通》提高版题目

    目录 2019.1.27 #10082. 「一本通 3.3 例 1」Word Rings 题意 思路 #10083. 「一本通 3.3 例 2」双调路径 题意 思路 #10084. 「一本通 3.3 ...

  6. LOJ 一本通一句话题解系列:

    第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...

  7. 图论常用算法之一 POJ图论题集【转载】

    POJ图论分类[转] 一个很不错的图论分类,非常感谢原版的作者!!!在这里分享给大家,爱好图论的ACMer不寂寞了... (很抱歉没有找到此题集整理的原创作者,感谢知情的朋友给个原创链接) POJ:h ...

  8. 转载 - 最短路&差分约束题集

    出处:http://blog.csdn.net/shahdza/article/details/7779273 最短路 [HDU] 1548    A strange lift基础最短路(或bfs)★ ...

  9. Word/Excel 在线预览

    前言 近日项目中做到一个功能,需要上传附件后能够在线预览.之前也没做过这类似的,于是乎就查找了相关资料,.net实现Office文件预览大概有这几种方式: ① 使用Microsoft的Office组件 ...

随机推荐

  1. tomcat服务器java.lang.OutOfMemoryError: PermGen space

    一挂就报内存溢出 下面是TOMCAT日志 JAVA程序是没有报错, Nov 24, 2009 4:07:02 PM org.apache.catalina.core.ApplicationDispat ...

  2. Spine学习六 - 碰撞检测

    相信在使用Spine做游戏的时候,肯定会遇到这样的需求: 一个人物有一把大刀,要使用这把大刀去砍怪,伤害检测以这把大刀砍刀怪物为准,那么要怎么在一个看上去就是一体的Spine Object上绑定一个碰 ...

  3. Spine学习四 - 在动作上绑定回调事件

    Spine事件特性: SpineEvent(string startsWith = "", string dataField = "", bool includ ...

  4. Web测试经典bug、安全性测试

    典型BUG 表格的排序.翻页.添加.删除的联合测试 输入框的长度检查 数据库表中如果指定utf8长度为150,则可以输入150个中文或英文字母等 (有时候界面判断失误,却只能输入50个汉字) 数据添加 ...

  5. 面试【JAVA基础】JVM

    1.内存模型 1.1.堆 堆是所有线程共享的,主要存放对象实例和数组. 新生代和老年代的比例是1:2. 新生代中三个区域的比例是 8 : 1 : 1. 1.1.1.新生代 对象分配在eden区中,当e ...

  6. java初探(1)之防止库存为负以及防超买

    在秒杀业务中,会出现当只剩一个库存时,但有多个人仍然秒杀成功,且都减库存成功,因此,在减库存,更新数据库的时候,需要在sql语句上进行判断,是否库存大于0. @Update("update ...

  7. 推荐一个IT老鸟肝了2月有余的免费开源WPF企业级开发框架

    一个新学WPF的IT老鸟,肝了2个月做了这么一个WPF企业级开发框架,站长clone学习,觉得甚是不错.这是一个使用了Prism搭建的插件式框架,封装了DataGrid的使用,使整个框架子模块简单易学 ...

  8. Oracle重做日志和日志挖掘

    重做日志-Redo log 首先给出参考资料: 1.Oracle官网-Managing the Redo Log 为什么需要redo log 内存中数据修改后,不必立即更新到磁盘---效率 由日志完成 ...

  9. Dos简易基础及常用Dos命令

    Dos简易基础及常用Dos命令 什么是cmd? cmd是command的缩写,意指操作系统中的命令行程序,一般说的都是Windows中的Dos系统. 如何打开cmd? 键盘操作:Win + R 输入c ...

  10. 单应用模式 - Layuiadmin单页版放入TP6.0的部署方案

    thinkphp6.0.3单应用模式.layuiadmin1.4.0单页版,不需要tp的视图驱动 1. 复制 src.start 两个文件夹 2. 粘贴到 thinkphp 的 public 目录下 ...