BuaaCoding 001-025 Problems and Solutions

  • PART I 水题(都是语言题)
  • PART II 简单基础算法题
    • 009 零崎的人间冒险Ⅰ (汉诺塔递归)
      • 题目
      • 分析
      • 解答
    • 010零崎的人间冒险Ⅱ (斐波那契快速幂)
      • 题目
      • 分析
      • 解答
    • 012 零崎的人间冒险Ⅲ (Horner Rule)
      • 题目
      • 分析
      • 解答
    • 014 Inverse number:Reborn(归并排序)
      • 题目
      • 分析
      • 解答
    • 015 零崎的人间冒险Ⅳ (快排)
      • 题目
      • 分析
      • 解答
    • 024 名侦探柯南之陷阱升级版 (模拟)
      • 题目
      • 分析
      • 解答
  • PART III 数学题
    • 011 Let's play a game (辗转相除法+博弈问题)
    • 025 质数判断
      • 题目
      • 分析
      • 解答

PART I 水题(都是语言题)

001 test a+b
002 求余
003 发糖
004 Kevin·Feng的正确@姿势
005 jhljx上小学 (开一个大字符数组)
006 三位数反转
007 Last_Day’s dog
008 creeper学妹的计算题
017 A+B
018 快来快来帮猪脚 平均数
019 大家快来刷TD啊 收尾法除法
020 水水哒a+b
021 大家都来分级啦
022 公公偏头痛 特殊字符输出
023 名侦探柯南之陷阱 细心的判断各种情况就好

PART II 简单基础算法题

009 零崎的人间冒险Ⅰ (汉诺塔递归)

题目

零崎最近一段时间非常无聊,于是他决定进行一场冒险,然而无聊的人遇到的冒险也非常的无聊,他的冒险刚刚开始就要结束了。 理由也非常的无聊,因为一个无聊的大魔王决定用一个非常有魔(wu)力(liao)的方式毁灭世界。 魔王有三个具有魔(wu)力(liao)的杆,暂时称为ABC,还有n个具有魔(wu)力(liao)的大小全都不同的盘子,这些盘子按照大小顺序放在A杆上,现在魔王要用具有魔(wu)力(liao)的方式移动到C杆,移动的过程中,小的盘子仍然只能摆在大的盘子上面而不能发生错乱,否侧魔王的魔法就会失灵。 然而魔王似乎想找一个无聊的人来替他完成这个魔法,而无聊的零崎也觉得这个事情非常的无聊,干脆就决定还是让你们去做。 零崎也不知道这个无聊的魔王到底有多少个有魔(wu)力(liao)的盘子,所以他说多少个你们就当是多少个吧。

分析

汉诺塔

解答

void hanoi(char src, char mid, char dst, int num){if (num == 0){return;}hanoi(src, dst, mid, num-1);  //上面n-1个借助dst移动到midprintf("%c to %c\n", src, dst); //最下面的移动到dsthanoi(mid, src, dst, num-1);   //mid上的n-1个移动到借助src移到dst
}

010零崎的人间冒险Ⅱ (斐波那契快速幂)

题目

零崎本以为他的无聊冒险马上就要结束了,然而实际上距离魔王的魔法成功发动还有很久很久,于是他的无聊冒险还可以继续…… 无聊的零崎需要给自己的冒险找点事做,然而实际上他的日常非常平和,如果说有什么意外的话,那就是他去打麻将了。零崎在玩一种叫做日式麻将的竞技游戏,然而无聊的零崎总是遭遇别人立直需要防守的场面。 零崎在防守时,会跟打现物和搏筋兜牌两种技能,然而为了不被婊得太惨,零崎不会连续搏筋兜牌。也就是说,零崎任意两次选择中不会都是搏筋兜牌。 那么对于n次舍牌,无聊的零崎会有多少种选择? 因为无聊的零崎可以打很久的麻将,所以n可能很大,无聊的零崎决定只要结果对100007求模后的选择数。

分析

一开始以为是动态规划,两个dp数组,dp1[n](dp2[n])表示第n次打(不打)的总选择数。dp1[n+1] = dp2[n],dp2[n+1] = dp1[n] + dp2[n],dp1[1] = 1, dp2[1] = 1,但是其实就是一个斐波那契数列,所以很简单。
另一个问题,输入范围很大INT_MAX,所以递归循环的fib都不能用,必须矩阵快速幂,简单的线性代数理论。不过写得有点丑,2*2的矩阵相乘直接循环展开了。。。。

解答

#include <iostream>
#define MAX 100
#define MOD 100007
using namespace std;
//step1 一开始以为是动态规划 找了一下规律发现是fibnacci
//常规求法不能应对INT_MAX 所以使用矩阵快速幂//2*2矩阵相乘
void two_dim_mult_mod(long long A[][2], long long B[][2], long long C[][2]) {//C = A * Blong long tmp[2][2] = {0, 0, 0, 0};tmp[0][0] = ((A[0][0]*B[0][0])%MOD + (A[1][0]*B[0][1])%MOD) % MOD;tmp[0][1] = ((A[0][0]*B[0][1])%MOD + (A[0][1]*B[1][1])%MOD) % MOD;tmp[1][0] = ((A[1][0]*B[0][0])%MOD + (A[1][1]*B[0][1])%MOD) % MOD;tmp[1][1] = ((A[1][0]*B[0][1])%MOD + (A[1][1]*B[1][1])%MOD) % MOD;C[0][0] = tmp[0][0];C[0][1] = tmp[0][1];C[1][0] = tmp[1][0];C[1][1] = tmp[1][1];
}//矩阵快速米
int fast_fib(int n){if (n==1) return 2;else if (n==2)   return 3;long long mat[2][2] = {1, 1, 1, 0};long long res[2][2] = {1, 0, 0, 1};int power = n - 2;while (power) {// 当前矩阵值需要乘到结果上if (power%2 == 1) {  two_dim_mult_mod(res, mat, res);}// 矩阵幂次翻倍two_dim_mult_mod(mat, mat, mat);power = power >> 1;}return (res[0][0]*3 + res[0][1]*2)%MOD;
}int main(int argc, char *argv[]) {int n;while(scanf("%d", &n)!=EOF){printf("%d\n", fast_fib(n)%MOD);}
}

012 零崎的人间冒险Ⅲ (Horner Rule)

题目

不打麻将的零崎特别的无聊,所以他又四处乱逛了。 四处乱逛的无聊零崎遇到了另一个特别无聊的人,因为这个人竟然在无聊的算各种一元n次多项式a0+a1x+a2x2+……+anxn!这个无聊的人算的实在太慢了令零崎忍不住想开启嘲讽模式,所以现在,快来给零崎搞一个能快速计算多项式的东西吧。(其实可能也不用特别快

分析

充分利用之前的计算结果。
多项式重写为((((anx)x + an-1)x + an-2)x + an-3)x

解答

#include <cstdlib>
#include <cstdio>
#define MOD 1000007
using namespace std;
int main(int argc, char *argv[]) {int n;int *p;while(scanf("%d", &n) != EOF) {p = (int*)malloc(sizeof(int)*(n+1));int x;scanf("%d", &x);int res = 0;for (int i = 0; i < n + 1; i++) {scanf("%d", p + n - i);}for (int i = 0; i <= n; i++) {res = (( ((res % MOD) * (x % MOD)) + p[i]) % MOD);}printf("%d\n", res);}
}

014 Inverse number:Reborn(归并排序)

题目

输入一个正整数n,随后给出一个长度为n的整数序列a1,a2,a3…an。求给定序列的逆序数。
概念回顾:
逆序对:数列a[1],a[2],a[3]…中的任意两个数a[i],aj,如果a[i]>a[j],那么我们就说这两个数构成了一个逆序对。
逆序数:一个数列中逆序对的总数。

分析

归并排序经典应用,以下几个编程细节注意一下就好。
1 注意结果是 long long
2 注意merge第二、三阶段不用再增加逆序数,因为逆序对的另一个元素已经算过一次了
3 注意归并排序最后复制回去数组下标有个变换
4 注意归并排序最后复制在while循环之外还有一个

解答

#include <cstdio>
#include <cstdlib>
#define MAXN 1000005
using namespace std;
int a[MAXN];
long long merge(int low, int high) {if (low == high) {return 0;}long long res = 0;int mid = (low+high) >> 1;res += merge(low, mid);res += merge(mid+1, high);int *tmp = (int*)malloc(sizeof(int)*(high-low+1));int lp = low, rp = mid+1;int k = 0;while(lp <= mid && rp <= high) {if (a[lp] <= a[rp]) {tmp[k++] = a[lp++];} else {tmp[k++] = a[rp++];res += (mid - lp + 1);}}while(lp <= mid) {tmp[k++] = a[lp++];}while(rp <= high) {tmp[k++] = a[rp++];}while(--k) {a[low + k] = tmp[k];}a[low] = tmp[0];return res;
}int main(int argc, char *argv[]) {int n;while(scanf("%d", &n)!=EOF) {for (int i = 0; i <n ;i++) {scanf("%d", &a[i]);}printf("%lld\n", merge(0, n-1));}return 0;
}

015 零崎的人间冒险Ⅳ (快排)

题目

在干掉了guangtou之后,无聊的零崎又去找事了……
说起来零崎前几周学到了一个叫做Apriori算法的东西,其第一步是挑出所有出现频率大于某个给定值的数据。然而作为一个具有一定程度的强(qiǎng )迫(pò)症的人,零崎显然希望先排个序再对其子集进行操作。
于是,现在的任务是简单的升序排列。

分析

快排,随机取轴明显快于取首。

解答

#include <cstdio>
#define MAXN 1000005
using namespace std;
int a[MAXN];
void quickSort(int low, int high) {if (low < high) {int choice = rand()%(high - low + 1) + low;int tmp = a[low];a[low] = a[choice];a[choice] = tmp;int r = a[low];int j = high, i = low;while(i < j) {while(a[j] >= r && i < j)j --;while(a[i] <= r && i < j)i++;int tmp = a[j];a[j] = a[i];a[i] = tmp;}a[low] = a[i];a[i] = r;int pivot = i;quickSort(low, pivot - 1);quickSort(pivot + 1, high);}return;
}
int main(int argc, char *argv[]) {int n;while(scanf("%d", &n) != EOF) {for (int i = 0; i < n; i++) {scanf("%d", &a[i]);}quickSort(0, n - 1);for (int i = 0; i < n; i++) {printf("%d ", a[i]);}printf("\n");}
}

024 名侦探柯南之陷阱升级版 (模拟)

题目

柯南在追捕犯人的时候掉入了没有井盖的深井,万幸他有阿笠博士发明的吸盘,但吸盘在掉下来的时候摔坏了,他每个小时能爬上一段距离。但在他休息的一瞬间中会滑下一段距离,幸运的是每隔一段距离有凹槽(自下而上)可以让柯南停止下滑,柯南需要编写代码来判断在自己能否爬出深井以及需要的时间,于是柯南开始敲代码。n,a,b,c,d均小于3000。

分析

这个题要是再各种判断就太麻烦了,所以使用模拟法,不担心模拟法超时是因为数字给了大小限制。

解答

#include <iostream>
//看到数字比较小可以考虑模拟
//a,表示井的深度。
//b,表示柯南每小时爬的距离。
//c,表示柯南每小时滑下的距离。
//d,表示隔多少米有凹槽。
#define max(a, b) (a > b? a:b)
using namespace std;
int main(int argc, char *argv[]) {int N;scanf("%d", &N);while(N--) {int a, b, c, d;scanf("%d%d%d%d", &a, &b, &c, &d);//考虑fail情况if (b < a && b <= c && b < d) { printf("fail\n");continue;   } //模拟int cur = 0;int rnd = 0;while(cur < a) {rnd++;cur += b;if (cur >= a) break;int bot1 = cur - c;if (cur < d) {cur = bot1;continue;}int bot2 = cur - (cur % d);cur = max(bot1, bot2);}printf("%d\n", rnd);}return 0;
}

PART III 数学题

011 Let’s play a game (辗转相除法+博弈问题)

这道题的细节分析很复杂,详见我的另一篇博文;

025 质数判断

题目

顾名思义,写一个可以判断一个整数是否为质数的程序。

分析

version1.0 所有比n小的都是一遍 必然超时。O(n)
version2.0 只需要试到sqrt(n)就行。O(sqrt(n))
version 2.5 试过2以后别的偶数都不用试了O(sqrt(n)/2)
version 3.0 大于等于5的质数一定和6的倍数相邻,所以可以每6个试两次。O(sqrt(n)/3)

解答

#include <cstdio>
#include <cmath>
using namespace std;
bool isPrime(int n) {if (n <= 3) {return (n-1) > 0;}if (n % 6 != 1 &&n % 6 != 5) {return false;}for (int i = 5; i < (int)sqrt(n) + 1; i+=6) {if (n % i == 0 || n % (i + 2) == 0) {return false;}}return true;
}
int main(int argc, char *argv[]) {int N;scanf("%d", &N);while(N--) {int n;scanf("%d", &n);if (isPrime(n)) printf("Yes\n");else printf("No\n");}return 0;
}

BuaaCoding 001-025 Problems and Solutions相关推荐

  1. BuaaCoding 026-050 Problems and Solutions

    BuaaCoding 026-050 Problems and Solutions PART I 水题 PART II 算法题 037 简单优先队列 (贪心 优先队列) 题目 分析 补充:c++优先队 ...

  2. AMC Problems and Solutions

    AMC Problems and Solutions:https://artofproblemsolving.com/wiki/index.php/AMC_Problems_and_Solutions ...

  3. Problems and Solutions

    1.Python相关 1.1 pip安装报错:is not a supported wheel on this platform 安装包是[pywin32-305-cp36-cp36m-win_amd ...

  4. 剑指 Offer(专项突击版)Java 持续更新....

    剑指 Offer(专项突击版) 刷题链接: https://leetcode-cn.com/problem-list/e8X3pBZi/?page=1 No.001 题目: 整数除法 1. 刷题链接: ...

  5. Google Interview University - 坚持完成这套学习手册,你就可以去 Google 面试了

    作者:Glowin 链接:https://zhuanlan.zhihu.com/p/22881223 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 原文地址:Goo ...

  6. [译] Google Interview University 一套完整的学习手册帮助自己准备 Google 的面试

    [译] Google Interview University 一套完整的学习手册帮助自己准备 Google 的面试 十一七天乐,看池博的github,发现这个markdown,转过来mark一下 原 ...

  7. Google Interview University | 坚持完成这套学习手册,你就可以去 Google 面试了

    Google Interview University 一套完整的学习手册帮助自己准备 Google 的面试 原文地址:Google Interview University 原文作者:John Wa ...

  8. 如何成为一名Google工程师

    [译] Google Interview University 一套完整的学习手册帮助自己准备 Google 的面试 原文地址:Google Interview University 原文作者:Joh ...

  9. 【C++】C++好书推荐

    一.吴咏炜推荐 1.入门级 Bjarne Stroustrup, A Tour of C++, 2nd ed. Addison-Wesley, 2018 中文版: 王刚译,<C++ 语言导学&g ...

最新文章

  1. 机器学习基石4-在何时才能使用机器学习(4)
  2. 求排列的逆序数(分治)
  3. MIME文件类型格式--汇总
  4. 36.迷宫(广度优先搜索)
  5. 一不小心就让Java开发者踩坑的fail-fast是个什么鬼?
  6. 1、数据库是什么?关系型数据库和非关系型数据库又是什么?
  7. Java 批量插入数据到数据库(MySQL)中
  8. 【Python】文本进度条
  9. CV Code | 计算机视觉开源周报20191002期
  10. vscode remote ssh_win10 下安装Vscode
  11. case / switch语句的Python等价物是什么? [重复]
  12. 相似度计算 java_Java基于余弦方法实现的计算相似度算法示例
  13. K_Nearest_Neighbot(knn)方法及其Pyhon 实现
  14. shell变量、函数和数组以及字符串的截取
  15. webpack中如何使用vue
  16. 微信小程序、小游戏反编译获取源码
  17. Jmeter HTTP Proxy Server 代理录制 IE无法录制到请求的问题解决
  18. Python爬虫实战 | (10) 爬取猫眼电影《海王》影评并存入MySql数据库
  19. Excel —— 录制宏
  20. Dubbo metrics学习总结

热门文章

  1. 算法分析:在象棋算式里,不同的棋子代表不同的数,有以下算式,设计一个算法求这些棋子各代表哪些数字。
  2. [luogu2294] [HNOI2005]狡猾的商人
  3. Kerberos简介、安装及与其它服务的集成和使用
  4. 13-津巴布韦-杂项
  5. 华为服务器租赁协议,华为云服务器租赁合同
  6. gel文件的作用——摘自百度
  7. css3 字体自动换行第二行缩进一格
  8. linux客户端显示fin_wait2,解决Linux服务器 FIN_WAIT2 连接过多的问题
  9. 网络自动化运维(NetDevOps)创作者推荐
  10. 计算机使用的显示器主要有两类,2015年计算机专转本预测题及答案