ACM程序设计竞赛基础教程

  • 前言
  • 分治算法
    • 计数问题(统计数字出现个数)
    • 查找等式的解(思维)
  • 递归算法
    • 汉诺塔问题
  • 贪心算法
    • 钓鱼问题

前言

鉴于本人原因,本文记录的是博主认为之前没有想过的思路和想法。同时由于博主能力有限,对于没有掌握的技巧就不在列举。详细的可以亲自读这本书。

分治算法

计数问题(统计数字出现个数)

题目大意
给定两个整数a和b,计算出1在a和b之间出现的次数。

解题思路
分治的思路是,我们先求出 0~a之间1的个数,与0 ~ b之间1的个数,之后这两者之差就是a ~ b 之间1的个数了。那么我们的问题变成了如何求0 ~ x 之间1的个数了。
将0 ~ 197的数列出来后可以看出以下规律:
①可以求出1在190197之间出现的次数,然后对于0189,1在个位数上出现了1次。
②个位考虑完后,直接考虑197/10-1(即18)中1出现的次数,同时考虑到,数字减小了,每一位的权值会增加,也就是说每一个数字出现的次数会增加10倍。例如,现在的1,是原来10~19之间的所有的1,即权值变为原来的10倍。

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;const int N = 11;
int d[N];
int val;void deal(int n){if(n <= 0) return ;int one ,ten;one = n % 10 , n /= 10; // one 当前位,ten 是高位ten = n;for(int i = 0 ; i <= one ; ++i)d[i] += val; // 将个位数上的数统计下来while(ten){ // 个位对于高位上数字的贡献d[ten%10] += (one + 1) * val;ten /= 10;}// 高位对当前位的贡献for(int i = 0 ; i <= 9 ; ++i)d[i] += n * val;d[0] -= val; // 将第一位是0的情况排除val *= 10; // 权值变化deal(n - 1);
}int main(){int a ,b;while(cin>>a>>b , a || b){if(a < b)swap(a,b);val = 1;memset(d , 0 ,sizeof d);deal(a);val = -1; // 为了求 deal(a) - deal(b)deal(b);cout<<d[1]<<endl;}return 0;
}

查找等式的解(思维)

题目大意
有3个数列A,B和C,有一个数X。计算是否存在三个整数,Ai,Bj,CkA_i ,B_j,C_kAi​,Bj​,Ck​,使得公式Ai+Bj+Ck=XA_i +B_j + C_k = XAi​+Bj​+Ck​=X成立。

解题思路:
我们首先把 a + b 的情况全部列出来放在一个数组中,之后对这个数组c中进行排序。然后二分枚举 s - c[i] 是否存在。

递归算法

汉诺塔问题

这是一个经典问题了,就不描述了。

解题思路:
在这本书中描述一个思路,这个思路或许可以用来作为汉诺塔非递归解答的一个思路。思路如下:
首先把3根柱子按顺序排成“品”字型,把所有的圆盘按从大到小的顺序放在柱子a上,根据圆盘的数量确定柱子的排放顺序;若n为偶数,按顺时针方向依次摆放a、b、c;若n为奇数,按顺时针方向依次摆放a、c、b。
①按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子α,则把它移动到b;若圆盘1在柱子b,则把它移动到c;若圆盘1在柱子c,则把它移动到a。
②接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。
③反复进行①和②操作,最后就能按规定完成汉诺塔的移动。
所以,结果非常简单,就是按照移动规则向一个方向移动金片。
例如,3阶汉诺塔的移动为:a→c,a→-b,C→→b,a→c,b→a,b→c,a→c

递归代码如下

思路:

  • 我们想象一下,有n个物品,我们先需要借助c,将上边的n-1个放到b中、之后家将最底下的放到c中。之后我们总借助与没有物品的柱子将没放到c柱的物品上边的n-1个放到其中,这后将底下的再移到c。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;int n;void move(int n ,char a,char b){printf("move %d from %c to %c\n",n,a,b);
}
// 意义是 n个物体,借助 b ,从 a ,移动到 c
void dfs(int n ,char a ,char b,char c){if(n == 1)move(1,a,c);else{dfs(n-1, a, c,b);move(n,a,c);dfs(n-1, b, a, c);}
}int main(){cin>>n;dfs(n,'a','b','c');return 0;
}

贪心算法

钓鱼问题

题目:约翰有h(1≤h≤16)个小时的时间,在该地区有n(2≤n≤25)个湖,这些湖刚好分布在一条路线上,该路线是单向的。约翰从湖1出发,他可以在任一个湖结束钓鱼。但他只能从一个湖到达另一个与之相邻的湖,而且不必每个湖都停留。已知在最初5分钟,湖i预计钓到鱼的数量为fi(fi≥0)。以后每隔5分钟,预计钓到鱼的数量将以常数di(di≥0)递减。如果某个时段预计钓到鱼的数量小于或等于di,那么在下一时段将钓不到鱼。为简单起见,假设没有其它的钓鱼者影响约翰的钓鱼数量。

解题思路
首先须注意的是,约翰只能向前走,若返回只会增加他在路上的时间,因而减少钓鱼的时间。因此此题解题步骤如下:
①枚举约翰经过的最后一个湖,每种情况减去所需步行的时间,剩下的就是钓鱼的时间。
②每5分钟选取钓鱼量最多的湖进行钓鱼,直到时间耗尽。
③在所有枚举的情况中选择钓鱼量最多的情况,即为问题的最优解。此题需要注意以下几个问题:
②随着时间的增加,在某个湖中的钓鱼数可能会出现负数,此时应将该湖中每个时间单位的钓鱼数更新为0。
①如果解不唯一,选择在第一个湖耗时最多的解;如果仍旧存在不唯一的解,选择在第二个湖耗时最多的解,以此类推。
③在测试数据或程序运行的过程中可能出现每个湖鱼数全为0的情况,需特别处理。④枚举时,结束的标志是剩余时间≤0。

对于每一次取最大的湖我们可以利用优先队列来维护

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
int n,h,time1[101],t=0,ans=0,sum,temp;
struct lake
{int num;int lose;bool operator < (const lake &a) const {return num<a.num;}
}l[101];
int main()
{priority_queue<lake>q;cin>>n>>h;h=h*60/5;for(int i=1;i<=n;i++)cin>>l[i].num;for(int i=1;i<=n;i++)cin>>l[i].lose;time1[0]=0;time1[1]=0;for(int i=1;i<=n-1;i++)cin>>time1[i+1];for(int i=1;i<=n;i++){t=0;temp=h;sum=0;for(int j=1;j<=i;j++)t+=time1[j];temp-=t;for(int j=1;j<=i;j++)q.push(l[j]);while(temp){lake l1=q.top();q.pop();if(l1.num<=0)break;sum+=l1.num;l1.num-=l1.lose;q.push(l1);temp--;}while(!q.empty())q.pop();if(sum>ans)ans=sum;}cout<<ans<<endl;return 0;
}

读ACM程序设计竞赛基础教程之-------技巧小结相关推荐

  1. [置顶]2010年东北大学ACM程序设计竞赛冬季校赛题解

    8题只做出4题比较easy的题,而且做得挺麻烦,看来还要多练练. AC的题如下 NEUOJ  1112 I Love Apple Description So many people love app ...

  2. “师创杯”山东理工大学第九届ACM程序设计竞赛 正式赛 F.校赛~校赛~【思维+规律题】

    校赛~校赛~ Time Limit: 1000MS  Memory Limit: 65536KB Submit  Statistic Problem Description SDUT 的校赛是从 20 ...

  3. 次短路问题(陕西师范大学第九届ACM程序设计竞赛-F 新冠病毒要回家)

    求到顶点v的次短路时,有两种情况,要么是到其他某个顶点u的最短路再加上u->v的边,要么是到某个顶点u的次短路再加上u->v的边. 一般我们用Dijkstra求得最短路(无负权边),由此我 ...

  4. 哈尔滨理工大学第五届ACM程序设计竞赛(热身)

    Link:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2234 土豪银行 Time ...

  5. 华南师大 2017 年 ACM 程序设计竞赛新生初赛题解

    华南师大 2017 年 ACM 程序设计竞赛新生初赛题解 华南师范大学第很多届 ACM 程序设计竞赛新生赛(初赛)在 2017 年 11 月 20 日 - 27 日成功举行,共有 146 名同学有效参 ...

  6. python程序设计与基础教程第六章上机实验_《Python程序设计与算法基础教程》教学大纲.doc...

    PAGE 1/ NUMPAGES 2 作者:江红.余青松 定价:59元 ISBN:9787302466833 <算法与程序设计>课程教学大纲 Programming and algorit ...

  7. 深入浅出程序设计竞赛 - 基础篇_Re: 从零开始的程序设计竞赛(三)

    Re: 从零开始的程序设计竞赛顾名思义,是一个力图介绍完全没有接触过程序设计竞赛的学校.老师及学生进入比赛的文章.文章包含如何参加比赛以及训练如何安排等内容.你可以查看过往的几期内容: Re: 从零开 ...

  8. 第十四届中北大学ACM程序设计竞赛 J.ZBT的游戏

    问题描述 第14届中北大学程序设计竞赛来了,集训队新买了一大堆气球,气球一共有K种颜色(1<=K<=256),气球的颜色从1-K编号. ZBT童心未泯,他发明了一种摆放气球的游戏,规则如下 ...

  9. 第十五届浙江省ACM程序设计竞赛小记

    因为前段时间一直在找实习的缘故,比赛前几乎没怎么练习,所以对这场比赛本不抱太大希望. 早上7.30在学校门口集合,坐着大巴去浙江大学紫金港校区比赛,这是第二年到浙江大学参加ACM竞赛,心情依旧是很欢悦 ...

最新文章

  1. 深入理解html5系列-文本标签
  2. 【数据库系统概论】考研重点章节分析【0】
  3. python3随记——字符编码
  4. 移动Web应用程序开发HTML5篇
  5. [转载]《STL源码剖析》阅读笔记之 迭代器及traits编程技法
  6. 实验三:shell编程(1)
  7. Spring Boot 2 尝鲜-动态 Banner
  8. Address already in use: bind JVM端口被占用解决方法
  9. 咪蒙,毕业两年成阿里P7,不止阿里HR不同意......
  10. 6个功能杰出的黑科技APP, 每一个都令你大开眼见!
  11. macbook电池用什么软件测试,Wattagio Mac_Wattagio For Mac(电池检测软件) v1.1苹果电脑版 - 121苹果网...
  12. word文档左侧没有显示文档的目录
  13. 维盟无线ap服务器地址,让WiFi飞起来!维盟室外无线AP桥接与中继配置方案
  14. Python - 使用ffmepg批量转换某个文件夹以及所有子文件夹下所有的视频,修改其帧率/码率/分辨率到另一文件夹,并保留原有文件夹结构
  15. EDK2 Build Flow
  16. 淘宝新版打标足迹在哪里浏览?
  17. 写作的意义,从一枚勋章开始
  18. 佐治亚理工计算机科学专业排名,佐治亚理工学院计算机科学硕士专业排名
  19. 【整理自官方公开资料】CSDN博主排名影响因素
  20. LC滤波器的截止频率公式

热门文章

  1. beyond compare 不自动比较解决办法(没解决,可以ctrl + F5手动比较)
  2. 电脑物理内存与虚拟内存的区别与关系
  3. Win10如何打开软键盘?
  4. tensorflow GPU笔记
  5. 初学__Python——Python 可重用结构:Python模块
  6. python语句结束标志_jinja2.exceptions.TemplateSyntaxError:预期标记“打印语句结束”,已“发布” - python...
  7. SpringBoot笔记:SpringBoot集成SpringbootAdmin监控
  8. ospf多区域配置为什么ping不通_「实战」动态路由多区域 OSPF 基本配置,一分钟了解下...
  9. 获取电脑的唯一识别码_教你如何知道自己的电脑能够装黑苹果
  10. QString之arg用法