Portal: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1345

     http://codeforces.com/gym/100803/attachments  A题

好题!

坑不多,切入比较难

一开始的想法是暴力,由于求得是最小解且此图太大无边界,所以不能DFS,首先想到BFS

解法1 BFS+STL queue

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<set>
  4. #include<cstdio>
  5. #include<cstdlib>
  6. #include<cmath>
  7. #include<queue>
  8. using namespace std;
  9. #define FOR(i,j,k) for(int i=j;i<=k;i++)
  10. #define FORD(i,j,k) for(int i=j;i>=k;i--)
  11. #define LL long long
  12. #define SZ(x) x.size()
  13. int vis[];
  14. int x,k,n,m,s,ans,start,end1,end2,dight;
  15. int bfs()
  16. {
  17. queue<int> q1,q2;
  18. q1.push(start);
  19. q2.push();
  20. vis[start]=;
  21. while(q1.front()!=end1&&q1.front()!=end2)
  22. {
  23. int fr=q1.front();
  24. int fv=q2.front();
  25. FOR(i,,n-)
  26. {
  27. if((fr&(<<i))&&!(fr&(<<(i+))))
  28. {
  29. ans=fr+(<<i);
  30. if(!vis[ans]) {vis[ans]=;q1.push(ans);q2.push(fv+);}
  31. }
  32. else if(!(fr&(<<i))&&(fr&(<<(i+))))
  33. {
  34. ans=fr-(<<i);
  35. if(!vis[ans]) {vis[ans]=;q1.push(ans);q2.push(fv+);}
  36. }
  37. }
  38. q1.pop();
  39. q2.pop();
  40. }
  41. return q2.front()-;
  42. }
  43. int main()
  44. {
  45. cin>>n>>m;
  46. dight=;
  47. FORD(i,n-,)
  48. {
  49. cin>>x;
  50. start+=x<<i;
  51. }
  52. int c=n;
  53. FOR(i,,m)
  54. {
  55. cin>>x;
  56. FOR(j,,x)
  57. {
  58. c--;
  59. end1+=dight<<c;
  60. end2+=(-dight)<<c;
  61. }
  62. dight^=;
  63. }
  64. cout<<bfs()<<endl;
  65. return ;
  66. }

蛋疼的代码

解法2 BFS+手写queue

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<set>
  4. #include<cstdio>
  5. #include<cstdlib>
  6. #include<cmath>
  7. //#include<queue>
  8. using namespace std;
  9. #define FOR(i,j,k) for(int i=j;i<=k;i++)
  10. #define FORD(i,j,k) for(int i=j;i>=k;i--)
  11. #define LL long long
  12. #define SZ(x) x.size()
  13. int vis[];
  14. int x,k,n,m,s,ans,start,end1,end2,dight;
  15.  
  16. int bfs()
  17. {
  18. int q1[];int L1=;int R1=;
  19. int q2[];int L2=;int R2=;
  20. q1[++R1]=start;
  21. q2[++R2]=;
  22. vis[start]=;
  23. while(q1[L1]!=end1&&q1[L1]!=end2)
  24. {
  25. int fr=q1[L1];
  26. int fv=q2[L2];
  27. FOR(i,,n-)
  28. {
  29. if((fr&(<<i))&&!(fr&(<<(i+))))
  30. {
  31. ans=fr+(<<i);
  32. if(!vis[ans]) {vis[ans]=;q1[++R1]=ans;q2[++R2]=fv+;}
  33. }
  34. else if(!(fr&(<<i))&&(fr&(<<(i+))))
  35. {
  36. ans=fr-(<<i);
  37. if(!vis[ans]) {vis[ans]=;q1[++R1]=ans;q2[++R2]=fv+;}
  38. }
  39. }
  40. L1++;
  41. L2++;
  42. }
  43. return q2[L2]-;
  44. }
  45. int main()
  46. {
  47. cin>>n>>m;
  48. dight=;
  49. FORD(i,n-,)
  50. {
  51. cin>>x;
  52. start+=x<<i;
  53. }
  54. int c=n;
  55. FOR(i,,m)
  56. {
  57. cin>>x;
  58. FOR(j,,x)
  59. {
  60. c--;
  61. end1+=dight<<c;
  62. end2+=(-dight)<<c;
  63. }
  64. dight^=;
  65. }
  66. cout<<bfs()<<endl;
  67. return ;
  68. }

同样的代码

比较同样情况下STL的queue和手写的queue,我发现STL的queue内存比手写的多了4KB

这是个严重的问题,因为STL经常pop元素,是动态的,它的内存一定较小,但即便在手写的queue固定大小为8e5个int的情况下,仍然多4KB,即1e3个int

STL的queue在此题理论上能够最多有16384个元素,所以事实上同等长度的queue所用内存相当于3到4倍同等int

所以,我们应该谨慎使用STL,为保险起见,用queue时数据输入的极限容量不得多于1e7,即1/10int在32768KB下容量左右

在解法1/2的代码中使用了位运算的黑科技

  1. FORD(i,n-,)
  2. {
  3. cin>>x;
  4. start+=x<<i;
  5. }
  6. int c=n;
  7. FOR(i,,m)
  8. {
  9. cin>>x;
  10. FOR(j,,x)
  11. {
  12. c--;
  13. end1+=dight<<c;
  14. end2+=(-dight)<<c;
  15. }
  16. dight^=;
  17. }
  18.  
  19. ///
  20.  
  21. if((fr&(<<i))&&!(fr&(<<(i+))))
  22. {
  23. ans=fr+(<<i);
  24. if(!vis[ans]) {vis[ans]=;q1[++R1]=ans;q2[++R2]=fv+;}
  25. }
  26. else if(!(fr&(<<i))&&(fr&(<<(i+))))
  27. {
  28. ans=fr-(<<i);
  29. if(!vis[ans]) {vis[ans]=;q1[++R1]=ans;q2[++R2]=fv+;}
  30. }

神奇的做法

其中(fr&(1<<i))&&!(fr&(1<<(i+1)))最妙

fr&(1<<i)表示判断fr的二进制表示中第i位是否为1(黑科技中利用了c++非0为真的机制)

这样使用黑科技的原因是这题中交换相同的二进制位是没有意义

所以仅仅交换01和10来产生当前数字的邻居

解法3 贪心

思路 先处理出start[]和两个可能的终点end1[] end2[]

再判断start到end的变换是否可行(检查01数量)

若可行,用K从1到n(maxlength)迭代

则对于 start[K]与endx[K]

若start[K]与endx[K]相同 不做任何操作

若start[K]与endx[K]不相同 则找到离K最近的J(J<K)使得 start[J]!=start[K] 使start[J]与start[--J]不停交换使得J最终等于K以完成start[K]与endx[K]相同的任务

此时操作增加了J-K次

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<set>
  4. #include<cstdio>
  5. #include<cstdlib>
  6. #include<cmath>
  7. //#include<queue>
  8. using namespace std;
  9. #define FOR(i,j,k) for(int i=j;i<=k;i++)
  10. #define FORD(i,j,k) for(int i=j;i>=k;i--)
  11. #define LL long long
  12. #define SZ(x) x.size()
  13. int start[],end1[],end2[];
  14. int x,c,k,n,m,s,ans,ans1,ans2,dight;
  15. bool check1()
  16. {
  17. int s[]={,};
  18. FOR(i,,n)
  19. s[start[i]]++;
  20. FOR(i,,n)
  21. s[end1[i]]--;
  22. if(s[]==&&s[]==) return true; else return false;
  23. }
  24. bool check2()
  25. {
  26. int s[]={,};
  27. FOR(i,,n)
  28. s[start[i]]++;
  29. FOR(i,,n)
  30. s[end2[i]]--;
  31. if(s[]==&&s[]==) return true; else return false;
  32. }
  33. int find1(int xx,int x)
  34. {
  35. int ss=x;
  36. while(ss<=n&&end1[ss]!=xx)
  37. ss++;
  38. if(ss==n+) return ; else return ss;
  39. }
  40. int find2(int xx,int x)
  41. {
  42. int ss=x;
  43. while(ss<=n&&end2[ss]!=xx)
  44. ss++;
  45. if(ss==n+) return ; else return ss;
  46. }
  47. int main()
  48. {
  49. cin>>n>>m;
  50. dight=;
  51. FOR(i,,n)
  52. cin>>start[i];
  53. FOR(i,,m)
  54. {
  55. cin>>k;
  56. FOR(j,,k)
  57. {
  58. c++;
  59. end1[c]=dight;
  60. end2[c]=-dight;
  61. }
  62. dight^=;
  63. }
  64. bool flag1=check1();
  65. bool flag2=check2();
  66. int zz=;
  67. if(flag1)
  68. while(zz!=n)
  69. {
  70. zz++;
  71. if(end1[zz]!=start[zz])
  72. {
  73. int findd=find1(start[zz],zz);
  74. end1[findd]^=;
  75. end1[zz]^=;
  76. ans1+=findd-zz;
  77. }
  78. }
  79. zz=;
  80. if (flag2)
  81. while(zz!=n)
  82. {
  83. zz++;
  84. if(end2[zz]!=start[zz])
  85. {
  86. int findd=find2(start[zz],zz);
  87. end2[findd]^=;
  88. end2[zz]^=;
  89. ans2+=findd-zz;
  90. }
  91. }
  92. if(flag1&&flag2) cout<<min(ans1,ans2)<<endl;
  93. else if(flag1) cout<<ans1<<endl;
  94. else cout<<ans2<<endl;
  95. return ;
  96. }

烂代码

coderforces Gym 100803A/Aizu 1345/CSU 1536/UVALive 6832 Bit String Reordering(贪心证明缺)的更多相关文章

  1. 贪心 UVALive 6832 Bit String Reordering

    题目传送门 /* 贪心:按照0或1开头,若不符合,选择后面最近的进行交换.然后选取最少的交换次数 */ #include <cstdio> #include <algorithm&g ...

  2. UVaLive 6832 Bit String Reordering (模拟)

    题意:给定一个01序列,然后让你你最少的操作数把这它变成目标. 析:由于01必须是交替出现的,那么我们就算两次,然后取最值. 代码如下: #pragma comment(linker, "/ ...

  3. csu - 1536: Bit String Reordering (模拟)

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1536 不知道为何怎么写都写不对. 这题可以模拟. 虽然题目保证一定可以从原串变成目标串,但是不一定 ...

  4. ACM学习历程—CSU 1216 异或最大值(xor && 贪心 && 字典树)

    题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1216 题目大意是给了n个数,然后取出两个数,使得xor值最大. 首先暴力枚举是C(n,  ...

  5. UVaLive 6609 Meeting Room Arrangement (贪心,区间不相交)

    题意:给定 n 个区间,让你选出最多的区间,使得每个区间不相交. 析:贪心题,贪心策略是按右端点排序,然后按着选即可. 代码如下: #pragma comment(linker, "/STA ...

  6. UVALive 4031 Integer Transmission(贪心 + DP)

    分析:求出最大值和最小值比较简单,使用贪心法,求最小值的时候我们让所有的0尽可能的向后延迟就可以了,求最大值则相反. 关键在于求出可以组合出的数字个数. 这就是组合数学版的dp了,我们让dp[i][j ...

  7. UVaLive 4628 Jack's socks (贪心)

    题意:给定一个无向图,让你把所有点的和它的任意一个相邻点匹配起来,问你是方案是不是唯一,如果是,则输出方案. 析:贪心,很容易知道,如果一个点的度数是 1,那么它只有一个相邻点,这样的话,我们就可以把 ...

  8. UVALive - 4636 Cubist Artwork(贪心)

    题目链接 题意 给出正视图和侧视图,判断最少用几个立方体 分析 若存在高度相同的立方块,则以数目多的那面为准. #include <iostream> #include <cstdi ...

  9. UVALive 3971 Assemble(二分+贪心)

    本题思路不难,但是要快速准确的AC有点儿考验代码功力. 看了大白书上的标程,大有所获. 用map和vector的结合给输入分组,这个数据结构的使用非常精美,恰到好处. #include<iost ...

随机推荐

  1. python全局变量语句global

    在python中使用函数体外的变量,可以使用global语句 变量可以是局部域或者全局域.定义在函数内的变量有局部作用域,在一个模块中最高级别的变量有全局作用域. 在编译器理论里著名的“龙书”中,阿霍 ...

  2. seo搜索优化教程11-seo搜索优化关键词策略

    为了使大家更方便的了解及学习网络营销推广.seo搜索优化,星辉科技强势推出seo搜索优化教程.此为seo教程第11课 关键词在seo搜索优化中有着重要的地位,本节主要讲解seo搜索优化中关键词优化的相 ...

  3. python.五角星

    import turtle turtle.pensize(4)turtle.pencolor("black") turtle.fillcolor("red")t ...

  4. guava限流器RateLimiter原理及源码分析

    前言 RateLimiter是基于令牌桶算法实现的一个多线程限流器,它可以将请求均匀的进行处理,当然他并不是一个分布式限流器,只是对单机进行限流.它可以应用在定时拉取接口数据, 预防单机过大流量使用. ...

  5. ES6—get 与 set

    在类里面可以去定义一些getter和setter,getter可以得到一些东西的方法,setter可以设置东西 class Chef{ constructor(food){ this.food = f ...

  6. 使用form 表单 弹出登录框,只传递数据,不刷新界面

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 2019计蒜客信息学提高组赛前膜你赛 #2(TooYoung,TooSimple,Sometimes Naive

    计蒜客\(2019CSP\)比赛第二场 巧妙爆零这场比赛(我连背包都不会了\(QWQ\) \(T1\) \(Too\) \(Young\) 大学选课真的是一件很苦恼的事呢! \(Marco\):&qu ...

  8. (转)协议森林02 小喇叭开始广播 (以太网与WiFi协议)

    协议森林02 小喇叭开始广播 (以太网与WiFi协议) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们在邮差与邮局中说到,以 ...

  9. [BUG]Uncaught TypeError: Illegal invocation at HTMLDivElement.

    <div id="clickMe" key="1">点我</div> clickMe.onclick = function (event ...

  10. MVC设计模式简介

    刚刚学习了MVC相关知识,在这里进行一下总结MVC设计模式提高了Java开发中的代码可读性,提高了开发效率,实乃开发利器 1在MVC中由客户端发送一个带参数的请求,经过servlet处理后做出相应的处 ...