刘汝佳《算法竞赛入门经典(第二版)》第三章习题(一)

习题3-1 得分(ACM/ICPC Seoul 2005,UVa1585)

给出一个由O和X组成的串(长度为1~80),统计得分。每个O的得分为目前连续出现的O的个数,X的得分为0。例如:OOXXOXXOOO的得分为1+2+0+0+1+0+0+1+2+3。

解析

因为X的得分为0,所以只需要统计O的得分,另外需要注意的是每次遇到X,统计O得分的变量都要置0。

#include <iostream>
#include <cstdio>using namespace std;int main (void)
{string s;cin >> s;int onum = 0,sum = 0;for (int i = 0; i < s.size(); i++){if (s[i] == 'O'){onum++;sum += onum;}else if (s[i] == 'X')onum = 0;}cout << sum << endl;return 0;
}

习题3-2 分子量(ACM/ICPC Seoul 2007,UVa1586)

给出一种物质的分子式(不带括号),求分子量。本题中的分子式只包含 4 种原子,分别为 C , H , O , N ,原子量分别为 12.01 , 1.008 , 16.00 , 14.01 (单位: g/mol )。例如: C6H5OH 的分子量为 94.108g/mol 。

解析

这道题在ACM/ICPC Seoul 2007中需要输入的是n(1≤n≤99)个分子量(管他呢),而且并没有给出数据范围和运行时间限制,所以暂且当做标准限制来做吧(下面的题目除非书中注明,否则同样看待)。

因为分子式中数字对应的一定是其前面的分子,所以只需要判断分子是哪个,以及分子后面的分子数,再根据对应分子的分子量计算就好了。然而麻烦就麻烦在分子数并不一定是个位数,所以我们要怎么将代表分子数的字符串转换成数字呢?c标准库提供了atoi,atof,atol,atoll函数(需包含头文件stdlib.h或cstdlib)将字符串分别转换成int,double,long,long long型,我们将两个分子之间的数字存放在一个字符型数组,再调用atof函数转换即可。

说起来挺简单的,但实现起来需要考虑的东西还蛮多。不废话,上代码:

#include <iostream>
#include <cstdlib>
#include <memory>
#include <cctype>using namespace std;const char name[] = "CHON";
const double fweight[] = {12.01,1.008,16.00,14.01};int main (void)
{char c[5];string s;cin >> s;double sum = 0.0, weight = 0.0;int num = 0;for (int i = 0; i < s.size(); i++)//遍历字符串,找出分子{if (isalpha(s[i])){for (int j = 0; j < 4; j++)//将分子对应的分子量赋给weightif (s[i] == name[j]){weight = fweight[j];break;}num = 0;//将用来移位的变量清零if (isalpha(s[i+1]) || i+1 == s.size())//分子式后面若没有分子数则其分子数默认为1sum += weight;else{for (int k = i+1; k < s.size() && isdigit(s[k]); k++)//将表示分子数的字符串转换为double型数据c[num++] = s[k];sum += atof(c)*weight;//计算分子量}memset(c, '\0', sizeof(c));//将用于存放分子数的数组清空}elsecontinue;}cout << sum << "g/mol" << endl;return 0;
}

习题3-3 数数字(ACM/ICPC Danang 2007,UVa1225)

把前n(n≤10000)个整数顺次写在一起:123456789101112…数一数0~9各出现多少次(输出10个整数,分别是0,1,…,9出现的次数)。

解析

刚看到这道题的时候我一直以为这些数字的出现是有规律的,想了很久,然而……失败了(等我用暴搜写完后在网上找各路大神的解法才悲剧地发现:根本没有规律T.T)。数据范围不大,原题的时间限制为3000ms,所以直接暴搜吧。有两种思路,第一种是对1~n的整数分别进行数字统计,得出结果;第二种是将1~n的整数一个个转成字符串,然后统计,得出结果。

对于第一种思路,一般做法是直接一个1~n的大循环,对每个整数一步步拆分,统计数字出现次数,我就是这么写的。另外我在网上看到一种比较特别的做法:直接用10000×10的二维数组做成一个查询表,再根据输入的值查询输出,下面是1~19的查询表,帮助理解:

解法一
#include <cstdio>
#include <memory>
#include <cstdlib>int main (void)
{int a[10];int n,num;scanf ("%d",&n);memset(a, 0, sizeof(a));for (int i = 1; i <= n; i++){int temp = i;while (temp)//拆分整数{num = temp%10;temp /= 10;a[num]++;}}for (int i = 0; i < 10; i++)(i == 0)?printf ("%d",a[i]):printf (" %d",a[i]);return 0;
}
解法二
#include <cstdio>
#include <memory>
#include <cstdlib>int a[10000][10];int main (void)
{memset (a, 0, sizeof(a));for (int i = 1; i < 10000; i++){for (int j = 0; j < 10; j++)a[i][j] = a[i-1][j];for (int k = i; k; k /= 10)a[i][k%10]++;}int n;scanf ("%d",&n);for (int j = 0; j < 9; j++)(j)?printf (" %d",a[n][j]): printf ("%d",a[n][j]);printf ("\n");return 0;
}

在本题中解法二相对于解法一在速度上并没有什么优势,但这个制表查询的想法还是值得学习的(反正我想不到- -)。

对于第二种思路,用sprintf函数(虽然itoa也可以,但与ANSI标准不兼容,不建议使用)将每个整数转成字符串是关键,直接看代码就好了。

解法三
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <cctype>int main (void)
{int num[10];int n;scanf ("%d",&n);char c[10];memset(num, 0, sizeof(num));//初始化存放统计数字的数组for (int i = 1; i <= n; i++)//对1~n的数字逐一统计{memset(c, '\0', sizeof(c));//初始化存放转换结果的字符数组sprintf(c, "%d", i);//将数字转换为字符存到数组c中for (int j = 0; j < 10; j++)//对字符数组c进行扫描,对数字进行统计if (isdigit(c[j])){switch (c[j]){case'0':num[0]++;break;case'1':num[1]++;break;case'2':num[2]++;break;case'3':num[3]++;break;case'4':num[4]++;break;case'5':num[5]++;break;case'6':num[6]++;break;case'7':num[7]++;break;case'8':num[8]++;break;case'9':num[9]++;break;}}}for (int i = 0; i < 10; i++)(i == 0)?printf ("%d",num[i]):printf (" %d",num[i]);return 0;
}

习题3-4 周期串(UVa 455)

如果一个字符串可以由某个长度为k的字符串重复多次得到,则称该串以k为周期。例如,abcabcabcabc以3为周期(注意,它也以6和12为周期)。

输入一个长度不超过80的字符串,输出其最小周期。

解析

题目已经说得很清楚,做法也很简单,只需要从1开始假设周期,然后扫描字符串的一半,验证是否是这个周期,是则输出周期,否则假设的周期增1。

#include <cstdio>
#include <string>
#include <cstdlib>int main (void)
{string s;int kase = 0,T = 0;//kase判断是否存在周期cin >> s;for (int i = 0; i < s.size()/2; i++)//扫描字符串的一半{T++;if (s.size()%T == 0){kase = 1;for (int j = 0; j < T; j++)//验证假设的第一个周期是否成立{for (int k = 0; k+T < s.size(); k += T)if (s[j] != s[k+j]){kase = 0;break;}if (!kase)//一旦发现周期不成立即退出,减少不必要的时间消耗break;}}if (kase)//同上一个kase作用相同break;}if (kase)printf ("%d\n",T);return 0;
}

刘汝佳《算法竞赛入门经典(第二版)》习题(三)相关推荐

  1. 刘汝佳算法竞赛入门经典 第二单元习题答案自编

    欢迎交流讨论! @2-1 #include <fstream> using namespace std;ifstream fin("aplusb.in"); ofstr ...

  2. 刘汝佳算法竞赛入门经典第三章习题

    /*给出一些容易理解的解题方法  但是没有oj评测 所以无法保证一定正确  矩阵的旋转给出了左旋和右旋 不确定题目3-5是哪一种*/ 习题3-1分数统计(stat) 输入一些学生的分数,哪个分数出现的 ...

  3. 算法竞赛入门经典(第二版) | 习题3-5 谜题 (UVa227,Puzzle)(World Finals 1993)

    乍一看是一个大水题,但World Finals这两个词标示着老子世界决赛真题虽然题目很水但是数据就能卡死你.整整搞了五个小时,期间经历过崩溃(花了这么多时间搞一道大水题,还没AC),但好在坚持下来了, ...

  4. 算法竞赛入门经典(第二版) | 习题3-10 盒子 (pair结构体)(UVa1587,Box)

    大意: 给定6个矩形的长和宽,判断他们能否构成一个长方体. 题目(提交)链接→UVa-1587 没使用过该网站的同学请猛戳这里→vJudge教程 储备知识: pair结构体: pair是将2个数据组合 ...

  5. UVa1588 | 算法竞赛入门经典(第二版) 习题3-11 换低档装置

    样例输入 2112112112 2212112 12121212 21212121 2211221122 21212 样例输出 10 8 15 解题思路: 最开始设想了四种情况, A固定, B左移或右 ...

  6. 算法竞赛入门经典 第二版 习题5-5 复合词 Compound Words uva10391

    题目:https://vjudge.net/problem/UVA-10391 思路:用vector存下单词,因为单词已按字典序排列于是复合词前半个单词一定在这个复合词之前,于是遍历寻找在首字母更变之 ...

  7. UVA-12171 雕塑 题解答案代码 算法竞赛入门经典第二版

    GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 这道题目在<算法竞赛入门经典第二版>书中标注了星号,也是第一道出现星号的 ...

  8. 补学图论算法:算法竞赛入门经典(第二版)第十一章:

    补学图论算法:算法竞赛入门经典(第二版)第十一章: 倒排索引还没有实现! 下面是左神的图论算法,并查集笔记.和一个美团题目. ''' https://www.nowcoder.com/live/11? ...

  9. 算法竞赛入门经典第二版课后习题答案第二章

    算法竞赛入门经典第二版课后习题答案 第二章 习题2-1水仙花数 输出100-999中的所有水仙花数.若三位数ABC满足ABC=A^3+B^3+C^3,则称其为水仙花数.例如153=1^3+5^3+3^ ...

  10. UVA-814 邮件传输代理的交互 题解答案代码 算法竞赛入门经典第二版

    GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 AC代码 #include<iostream> #include< ...

最新文章

  1. app:compileDebugJavaWithJavac
  2. C++之智能指针和普通指针单例模式两种实现
  3. 开工第一天,这个超时问题把我干趴下了
  4. matlab安装第三方库,Matlab调用cpp+第三方库
  5. 无心剑随感《程序人生乐无穷》
  6. linux ldd命令详解
  7. doubango的帧率太低,怎么解决?
  8. NetSarang旗下网络通讯系列产品v5版本更新合集丨附下载
  9. 微信加人就服务器频繁,微信加同一个人好友,提示操作过于频繁,请稍后重试!这个是什么意思啊?...
  10. 前端项目搭建基本流程
  11. 云从科技的Pixel-Anchor论文解读
  12. Linux内核分析及内核编程
  13. JVM总结(三)Minor GC、Major GC和Full GC
  14. 【转】ArcGIS server如何将自己的小地图叠加到Google maps或者Virtual Earth上
  15. Python 中的json.load() 和json.loads()
  16. ReLU函数 Vs Sigmoid 函数——XOR问题究竟用那个好
  17. 计算机作品三等奖——飞翔吧,七彩的梦
  18. 陶瓷天线的选型(二)
  19. 11:C语言之求sn=a+aa+aaa+aaaa+......的值
  20. 关于PMIC上CHG_LED_SINK引脚控制

热门文章

  1. 2023年科普新书大盘点:重磅新书,值得期待!
  2. 找不到模块“react”或其相应的类型声明。ts(2307)
  3. GB28181协议实现系列之----PS流封装(6)
  4. Android(国际化)多语言的实现和切换
  5. 第5章_数据库相关(一)
  6. 阿根廷绝杀尼日尼亚给我们互联网建站者带来什么启示?
  7. Aloam+deeplabv3+ 构建语义地图+行人车辆检测(kitti数据集)
  8. Yii2本身自带实现用户注册、登录
  9. 我的同事们(一):Alex Peng
  10. SH-SSS丨跨年龄声纹识别:学习年龄不变的说话人特征