唔..NOIP2010比较简单,总体感觉不错.

Problem 1: 机器翻译

水题,队列的简单应用.

读入时判断是否在内存中,可以用hash优化.如果不在内存中push进内存,放不下了pop header不用说了.上代码(未hash优化)

  1. //Bazinga!
  2. #include "cstdio"
  3. int sum,i,m,n;
  4. struct Q{
  5. int len,head,tail,qub[],i;
  6. void push(int n){
  7. qub[tail]=n;
  8. ++tail;
  9. if(len==m){
  10. ++head;
  11. }else{
  12. ++len;
  13. }
  14. }
  15. void has(int n){
  16. for(i=head;i<tail;++i){
  17. if(qub[i]==n){
  18. return;
  19. }
  20. }
  21. push(n);
  22. ++sum;
  23. }
  24. } q;
  25. int main(){
  26. scanf("%d%d",&m,&n);
  27. while(n--){
  28. scanf("%d",&i);
  29. q.has(i);
  30. }
  31. printf("%d", sum);
  32. return ;
  33. }

Click to see my ugly code.

hash优化版(不加也没关系...加了纯属多耗内存,但是在大数据前肯定要快.)

  1. #include "cstdio"
  2. int sum,i,m,n;
  3. bool h[];
  4. struct Q{
  5. int len,head,tail,qub[],i;
  6. void push(int n){
  7. h[qub[tail]=n]=true;
  8. ++tail;
  9. if(len==m){
  10. h[qub[head]]=false;
  11. ++head;
  12. }else{
  13. ++len;
  14. }
  15. }
  16. void has(int n){
  17. if(h[n]) return;
  18. push(n);
  19. ++sum;
  20. }
  21. } q;
  22. int main(){
  23. scanf("%d%d",&m,&n);
  24. while(n--){
  25. scanf("%d",&i);
  26. q.has(i);
  27. }
  28. printf("%d", sum);
  29. return ;
  30. }

DON'T CLICK ME

Problem 2: 乌龟棋

非常经典的动态规划题目,不算难,但是对刚接触DP的人来说也不容易.

设$f[i,j,k,l]$为1格卡~4格卡各使用了i~l张能获得的最高分,则动规方程为

$f[i,j,k,l]=score[i+2j+3k+4l]+max\left( f[i-1,j,k,l],f[i,j-1,k,l],f[i,j,k-1,l],f[i,j,k,l-1]\right)$

边界条件$f[0,0,0,0]=score[0]$..

上代码:

  1. //ug! So comfortable!
  2. #include "cstdio"
  3. int f[][][][],c[],s[],m,n,i,j,k,l;
  4. int t1,t2,t3,t4,t5;
  5. inline int mx(int a,int b){if(a>b){return a;}else{return b;}}
  6. int main(){
  7.     scanf("%d%d",&n,&m);
  8.     for(i=;i<n;++i){
  9.         scanf("%d",&s[i]);
  10.     }
  11.     for(i=;i<m;++i){
  12.         scanf("%d",&j);
  13.         ++c[j];
  14.     }
  15.     t1=c[];
  16.     t2=c[];
  17.     t3=c[];
  18.     t4=c[];
  19.     for(i=;i<=t1;++i){
  20.         for(j=;j<=t2;++j){
  21.             for(k=;k<=t3;++k){
  22.                 for(l=;l<=t4;++l){
  23.                     t5=j+k+(l<<);
  24.                     t5<<=;
  25.                     if(i>) f[i][j][k][l]=mx(f[i][j][k][l],f[i-][j][k][l]);
  26.                     if(j>) f[i][j][k][l]=mx(f[i][j][k][l],f[i][j-][k][l]);
  27.                     if(k>) f[i][j][k][l]=mx(f[i][j][k][l],f[i][j][k-][l]);
  28.                     if(l>) f[i][j][k][l]=mx(f[i][j][k][l],f[i][j][k][l-]);
  29.                     f[i][j][k][l]+=s[t5+i+k];
  30.                 }
  31.             }
  32.         }
  33.     }
  34.     printf("%d", f[t1][t2][t3][t4]);
  35.     return ;
  36. }

Don't touch me.

Problem 3: 关押罪犯

一道使用并查集的贪心算法题.输入所有怨气值,从大到小排序,一个个减小看有没有与现有的方案冲突;若冲突,输出当前怨气值,退出;不冲突,输出0.

一般解法是利用二分图二分答案,这样的时间复杂度是$\left( \text{It's really not clear. Depends on one's code.}\\ \text{There are many ways to implement the algorithm}\\ \text{and does not contains the same time complexity,}\\ \text{pretty sorry but I can't help.}\right)$.这样的想法很明确,但是不好写,而且慢.

用并查集写的,很短,很快,时间复杂度大约$\text{O}\left( \alpha\left( n\right) m\right)$.

顺便贴上我的代码:

  1. #include "cstdio"
  2. #include "algorithm"
  3. using namespace std;
  4. struct edge{
  5. int a,b,c;
  6. bool operator <(const edge x)const{
  7. return c>x.c;
  8. }
  9. } e[];
  10. int n,m,f[],x,y,t,p,i,j;
  11. int find(int x){
  12. t=x;
  13. p=x;
  14. //find root
  15. while(t=f[t],t!=x){
  16. x=t;
  17. }
  18. //path compressing
  19. while(f[p]=t,p=f[p],p!=t){};
  20. return t;
  21. }
  22. int main(){
  23. scanf("%d%d",&n,&m);
  24. for(i=;i<m;++i){
  25. scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
  26. }
  27. t=n<<;
  28. for(i=;i<=t;++i){
  29. f[i]=i;
  30. }
  31. sort(e,e+m);
  32. for(i=;i<m;++i){
  33. x=find(e[i].a);
  34. y=find(e[i].b);
  35. if(x==y){
  36. printf("%d", e[i].c);//largest
  37. return ;
  38. }
  39. f[y]=find(e[i].a + n);
  40. f[x]=find(e[i].b + n);
  41. }
  42. printf("");
  43. return ;
  44. }

There is nothing more I could tell you..All right, others' code encourages man.

Problem 4: 引水入城

这是一道非常综合的题目,分两个小题.

1) 是否所有沙漠城市都有水供应. BFS即可
2) 最少需要多少个湖泊城市建立抽水站

而第 2) 小题仔细想又可以分为

2.1) 求每个湖泊城市覆盖的沙漠城市范围
2.2) 求如何用最少的线段覆盖整条线段

第一个BFS可过,用一种类似DP的方法亦可(这种方法存在反例,但是数据比较弱,除了第一个测试数据跑不过以外全可,非常快).
第二个贪心.

$\text{The final tip:}$

$\text{Be careful using DFS because of system stack overflow and it's performance loss.}\color{orange}{\text{YOU'VE BEEN WARNED}}$

  1. I TOLD YOU DONT LOOK AT THIS BUT YOU ARE NOT LISTENING!!!!
  2. #include "cstdio"
  3. #include "algorithm"
  4. using namespace std;
  5. struct edge{
  6. int a,b,c;
  7. bool operator <(const edge x)const{
  8. return c>x.c;
  9. }
  10. } e[];
  11. int n,m,f[],x,y,t,p,i,j;
  12. int find(int x){
  13. t=x;
  14. p=x;
  15. //find root
  16. while(t=f[t],t!=x){
  17. x=t;
  18. }
  19. //path compressing
  20. while(f[p]=t,p=f[p],p!=t){};
  21. return t;
  22. }
  23. int main(){
  24. scanf("%d%d",&n,&m);
  25. for(i=;i<m;++i){
  26. scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
  27. }
  28. t=n<<;
  29. for(i=;i<=t;++i){
  30. f[i]=i;
  31. }
  32. sort(e,e+m);
  33. for(i=;i<m;++i){
  34. x=find(e[i].a);
  35. y=find(e[i].b);
  36. if(x==y){
  37. printf("%d", e[i].c);//largest
  38. return ;
  39. }
  40. f[y]=find(e[i].a + n);
  41. f[x]=find(e[i].b + n);
  42. }
  43. printf("");
  44. return ;
  45. }

Okay..It's wrong.

  1. #include "cstdio"
  2. #include "algorithm"
  3. #define max(a,b) (a>b?a:b)
  4. struct visitQueue
  5. {
  6. short x[],y[];
  7. int h,t;
  8. } vq;
  9. #define pushq(xa,ya) vq.x[vq.t]=xa,vq.y[vq.t]=ya,++vq.t;
  10. bool v[][];
  11. int i,j,k,l,m,n,t,s;
  12. int h[][],f[][];
  13. struct range{
  14. int s,e;
  15. } r[];
  16. bool cmp(range a,range b){
  17. return a.s<b.s;
  18. }
  19. void bfs(int x,int y){
  20. if(v[x][y]) return;
  21. vq.h=;
  22. vq.t=;
  23. vq.x[]=x;
  24. vq.y[]=y;
  25. v[x][y]=true;
  26. while(vq.h!=vq.t){
  27. i=vq.x[vq.h];
  28. j=vq.y[vq.h];
  29. k=h[i][j];
  30. if(i>&&h[i-][j]<k&&(!v[i-][j])){
  31. v[i-][j]=true;
  32. pushq(i-,j);
  33. }
  34. if(i<m&&h[i+][j]<k&&(!v[i+][j])){
  35. v[i+][j]=true;
  36. pushq(i+,j);
  37. }
  38. if(j>&&h[i][j-]<k&&(!v[i][j-])){
  39. v[i][j-]=true;
  40. pushq(i,j-);
  41. }
  42. if(j<n&&h[i][j+]<k&&(!v[i][j+])){
  43. v[i][j+]=true;
  44. pushq(i,j+);
  45. }
  46. ++vq.h;
  47. }
  48. }
  49. int main(){
  50. scanf("%d%d",&m,&n);
  51. for(i=;i<=m;++i){
  52. for(j=;j<=n;++j){
  53. scanf("%d",&h[i][j]);
  54. }
  55. }
  56. ///////////
  57. // if(m==2&&n==5&&h[2][3]==6&&h[1][5]==3){
  58. // printf("1\n1");//a hack for the first testing data. Remove this block
  59. // return 0;
  60. // }
  61. ///////////
  62. for(l=;l<=n;++l){
  63. bfs(,l);
  64. }
  65. t=;
  66. for(j=;j<=n;++j){
  67. if(!v[m][j]) ++t;
  68. }
  69. if(t>){
  70. printf("0\n%d",t);
  71. return ;
  72. }
  73. printf("1\n");
  74. for(j=;j<=n;++j){
  75. if(h[m][j-]<h[m][j] && j>){
  76. f[m][j]=f[m][j-];
  77. }else{
  78. f[m][j]=j;
  79. }
  80. }
  81. for(i=m-;i>;--i){
  82. for(j=;j<=n;++j){
  83. f[i][j]=f[i+][j];
  84. if(j> && h[i][j-]<h[i][j] && f[i][j-]<f[i][j]){
  85. f[i][j]=f[i][j-];
  86. }
  87. }
  88. }
  89. for(j=;j<=n;++j){
  90. r[j].s=f[][j];
  91. }
  92. for(j=n;j>;--j){
  93. if(h[m][j+]<h[m][j]&&j<n){
  94. f[m][j]=f[m][j+];
  95. }else{
  96. f[m][j]=j;
  97. }
  98. }
  99. for(i=m-;i>;--i){
  100. for(j=n;j>;--j){
  101. f[i][j]=f[i+][j];
  102. if(j<n&&h[i][j+]<h[i][j]&&f[i][j+]>f[i][j]){
  103. f[i][j]=f[i][j+];
  104. }
  105. }
  106. }
  107. for(j=;j<=n;++j){
  108. r[j].e=f[][j];
  109. }
  110. std::sort(r,r+n,cmp);
  111. l=;
  112. i=;
  113. s=;
  114. while(i<=n && s<n){
  115. if(r[i].s <= s+){
  116. ++l;
  117. k=;
  118. while(i<=n && r[i].s<=s+){
  119. if(r[i].e>k){
  120. k=r[i].e;
  121. }
  122. ++i;
  123. }
  124. s=k;
  125. }
  126. }
  127. printf("%d",l);
  128. return ;
  129. }

The code is this, exactly.

NOIP 2010题解的更多相关文章

  1. 洛谷NOIp热身赛题解

    洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...

  2. 洛谷 P1525 关押罪犯==codevs 1069 关押罪犯[NOIP 2010]

    P1525 关押罪犯 513通过 1.4K提交 题目提供者该用户不存在 标签图论并查集NOIp提高组2010 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 咳咳.竟MLE了. 囧.运行时错误 ...

  3. NOIp 2010/Luogu P1525 关押罪犯 【二分图/并查集】 By cellur925

    题目传送门 感想:相信自己的想法!继续挖掘! 读完题目后:看到的最大值最小?二分答案啊!再仔细一看:wi达到了1e9,二分可能费点劲.(其实真的是可以的)而且check函数貌似并没有什么行之有效的写法 ...

  4. [NOIP 2010]饮水入城 搜索+贪心

    考试的时候写了个dfs找出来了,最后处理的时候想到了贪心,但是正确性没有想通.然后想了想动规,也没想通.最后没办法,用状态的话用了个状压,弄了40分. 正解是bfs+贪心.Dfs也有过的. 下面题解引 ...

  5. 历年NOIP选题题解汇总

    联赛前上vijos板刷往年联赛题,使用在线编辑编写代码,祝我rp++. 废话不多说,挑比较有意思的记一下. 题目是按照年份排序的,最早只到了03年. 有些题目因为 我还没写/很早之前写的忘了 所以就没 ...

  6. NOIP 2010

    tags: NOIP 并查集 动态规划 搜索 categories: 信息学竞赛 总结 机器翻译 乌龟棋 关押罪犯 引水入城 机器翻译 Solution 维护一个队列, 每次从词典中查词时将单词加入队 ...

  7. noip 2010 关押罪犯 (二分图染色 并茶几)

    /* 二分图染色版本 两个监狱对应二部图的两部分 在给定的怨气值里二分 对于每一个Ci 进行染色判断是否合法 染色的时候 如果这条边的ci > Ci 这两个人就带分开 即染成不同的颜色 如果染色 ...

  8. Luogu P1082 同余方程(NOIP 2012) 题解报告

    题目传送门 [题目大意] 求关于x的同余方程 ax≡1(mod b)的最小整数解. [思路分析] 由同余方程的有关知识可得,ax≡1(mod b)可以化为ax+by=1,此方程有解当且仅当gcd(a, ...

  9. [NOIP 2010] 引水入城

    搜索+贪心. 参考博客:http://blog.sina.com.cn/s/blog_8442ec3b0100xib1.html 主要是要看出来,如果有解的话,每个沿湖城市能够流到的范围是连续的区间. ...

随机推荐

  1. 上下联动,右侧按钮过多poper展示

    http://pan.baidu.com/s/1dDFMLjF

  2. Python Paramiko模块与MySQL数据库操作

    Paramiko模块批量管理:通过调用ssh协议进行远程机器的批量命令执行. 要使用paramiko模块那就必须先安装这个第三方模块,仅需要在本地上安装相应的软件(python以及PyCrypto), ...

  3. Tomcat编码问题及访问软链接文件设置

    Tomcat编码问题及访问软链接文件设置 一.编码问题:让其支持UTF-8格式 修改tomcat中server.xml Connector port=" protocol="org ...

  4. 整理一下Entity Framework的查询

    整理一下Entity Framework的查询 2012-08-30 13:41:59 标签:Entity Framework 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信 ...

  5. phpcms使用细节

    1.在模板中使用php语句 <?php for ($i=0; $i < 10; $i++) {     echo $i."#######<br>"; }?& ...

  6. php-fpm进程关闭与重启脚本详解(转)

    先来理解一下什么是php-fpm PHP-FPM是一个PHP FastCGI管理器,是只用于PHP的. PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中.必须将 ...

  7. webservice报错Message part refundRequest was not recognized. (Does it exist in service WSDL?)

    最近在做一个支付的接口. 因为接口方使用webservice交互.  我只能去学习了下webservice 现在出了一个很古怪的问题~  我在请求他们url的时候, 返回给我找不到控制名错误 Mess ...

  8. MySQL里的found_row()与row_count()的解释及用法

    MySQL中有两个函数来计算上一条语句影响了多少行,不同于SqlServer/Oracle,不要因为此方面的差异而引起功能问题   出处:mysqlpub.com MySQL中有两个函数来计算上一条语 ...

  9. html中 table的结构 彻底搞清 caption th thead等

    正因为有太多 随意 称呼的 教法, 所以 感到很困惑, 如, 很多人把th叫标题. 那人家 caption怎么想, th只是一个跟td一样的角色, 只是对他进行加粗 加黑了而已, 用于某些单元格的内容 ...

  10. Alice and Bob 要用到辗转相减

    Alice and BobTime Limit: 1 Sec  Memory Limit: 64 MBSubmit: 255  Solved: 43 Description Alice is a be ...