1. 使CPU占有率画出正弦曲线

linux下的代码:

#if 0
/** Q1.1*/
int get_tick_count(){struct timeval tv;gettimeofday(&tv,NULL);return tv.tv_sec*1000000+tv.tv_usec;
}
const int Interval=300;
const int COUNT=300;
const double split=0.01;
const double PI=3.1415926;int main(){int busySpan[COUNT];int idleSpan[COUNT];int half=Interval/2;int radian=0;for(int i=0;i<COUNT;i++){busySpan[i]=(int)(half+sin(PI*radian)*half);idleSpan[i]=Interval-busySpan[i];}int j=0;int start;while(true){j=j%COUNT;start=get_tick_count();while(get_tick_count()-start<=busySpan[j]);sleep(idleSpan[j]);j++;}
}#endif

2. 中国象棋将帅问题

有三种方法:

方法1:

使用一个字节, 高4位表示A的位置,然后低4位表示B的位置, 然后剩下的就是分别对高4位和低4位进行操作了.

代码如下, 对位操作都是用宏实现的, 这样就不会占用其他变量了.

#if 0
/** Q1.2*/
#include <iostream>
#define OFFSET 4
//#define FMASK 0xFF
#define LMASK 0xF0
#define RMASK 0x0F
#define LGET(b) ((LMASK&b)>>OFFSET)
#define RGET(b) (RMASK&b)
#define RSET(b,n) (b=((LMASK&b)|n))
#define LSET(b,n) (b=((RMASK&b)|n<<OFFSET))
int main(){unsigned char b;int i=0;for(LSET(b,1);LGET(b)<=9;LSET(b,LGET(b)+1)){for(RSET(b,1);RGET(b)<=9;RSET(b,RGET(b)+1)){if(LGET(b)%3==RGET(b)%3)continue;cout<<"A:"<<LGET(b)<<' '<<"B:"<<RGET(b)<<endl;i++;}}cout<<i<<endl;
}
#endif

方法2:

使用一个char类型变量, 由于A和B的位置个数都是9个, 所以我们将”AB”想象成一个9进制的二位数, 那么该9进制数最小为0, 最大为80, 我们的工作就是取出该9进制的高位和低位, 然后判断高位和低位是否符合要求.

代码如下:

#if 0
/** Q1.2*/
int main(){char b=81;int i=0;while(b--){if(b/9%3==b%9%3)continue;cout<<"A:"<<b/9<<' '<<"B:"<<b%9<<endl;i++;}cout<<i<<endl;
}#endif

方法3:

方法3和方法1类似, 只是采用了另一种的思考方式, 使用了C/C++的struct的一个特殊用法:位域.

代码如下:

#if 0
/** Q1.2*/
struct _p{unsigned char a:4;unsigned char b:4;
}p;
int main(){int i=0;for(p.a=1;p.a<=9;p.a++)for(p.b=1;p.b<=9;p.b++) {if(p.a%3==p.b%3)continue;cout<<"A:"<<p.a%3<<' '<<"B:"<<p.b%3<<endl;i++;}cout<<i<<endl;
}#endif

3. 烙饼排序

基本思路:

4. 买书问题

分析:

这个题先考虑贪心算法, 优先考虑最大的折扣, 但是我们可以发现贪心策略会失效的:

再考虑动态规划的方法:

为了更好的使用动态规划的方法, 我们要考虑一下如何表示所出现的中间状态.

我们使用Xi表示第i(1<=i<=5) 卷购买数量. F(X1,X2,X3,X4,X5)表示所需要的费用. 从题目的要求中我们可以看出, Xi之间的大小关系是无关紧要的, 因为打折的方法只是要求卷不同, 与具体是哪一卷无关. 为了更好的表示, 我们利用(Y1,Y2,Y3,Y4,Y5)且Y1>=Y2>=Y3>=Y4>=Y5来表示(X1,X2,X3,X4,X5)的所有排列.

这样可以得到状态转移方程:

5. 快速找出故障机器

这儿给出了4种解法:

方法1:

最直接的方法就是对这个ID列表进行遍历, 同时记录每个ID出现的次数, 根据最后记录得到的次数很容易找到出现一次的ID. 不论有几台机器死机, 这种情况都可以完成. 这种情况的时间复杂度是O(N), 空间复杂度是O(N)

方法2:

由于在这个问题中, 大部分ID出现的次数都是2, 所以这个2我们可以不必存储.

做法就是: 使用一个变长数组记录ID出现的次数, 如果某个ID出现次数等于2, 则删除这个ID, 则最后剩下的ID就是出现一次的ID. 这个方法最好情况下空间为O(1), 最坏为O(N)

方法3:

这个方法的思想是寻找一个函数, 该函数利用所有的ID可以计算出缺失的ID. 这样的一个函数比较典型的是异或运算, 由于异或运算满足结合律和交换律, 所以将所有ID进行异或之后, 如果ID出现两次, 结果就为0, 这样最终的结果就是只出现一次的ID.

如果只有一台机器死机, 那么该ID就是所求的ID. 如果有两台机器死机, 比如A和B, 如果A=B那么A⊕B=0, 就是说一份数据的两个拷贝都丢失了, 这样我们就没法确认是哪个了. 如果A⊕B不为0, 那么其结果中肯定有一位为1,这样就根据该位是否为1将所有的ID分为两类:一类是该位为1, 一类是该位为0, 这样两类ID分别异或就得到了A和B.

方法4:

该方法是寻找所有ID的一个不变量, 这个不变量就是所有ID的和.所以可以预先计算出所有ID的和,然后再计算出当前所有ID和, 两者的差就是出现一次的ID. 如果是有两个ID出现一次的话,则x+y=a. 这样为了求出x和y, 我们还必须找出一个方程. 可以用同样的方式计算x*y=b, 或者x^2+y^2=c,这样都可以求出x和y.

1.6 饮料供货

1.7 光影切割问题

1.8 电梯调度算法

代码如下:

void best_floor(int *presons,int n,int &floor,int& min_floors){if(persons==0||n<=0)return;floor=-1;min_floors=0x7fffffff;int count=0;for(int i=0;i<n;i++){for(int j=1;j<i;j++)count+=persons[j]*(i-j);for(int j=i+1;j<n;j++)count+=persons[j]*(j-i);if(floor==-1||min_floors>count){min_floors=count;floor=i;}}
}

代码如下:

void best_floor2(int *presons,int n,int &floor,int& min_floors){if(persons==0||n<=0)return;int N1=0,N2=persons[0],N3=0;min_floors=0;for(int i=1;i<n;i++){N3+=persons[i];min_floors+=persons[i]*i;}for(int i=1;i<n;i++){if(N1+N2<N3){floor=i;min_floors+=(N1+N2-N3);N1+=N2;N2=persons[i];N3-=persons[i];}elsebreak;}
}

1.9 高效的安排见面会

1.11 NIM(1) 一排石头的游戏

1.12 NIM(2)

问题:

有N块石头和两个玩家A和B,玩家A先将石头随机分成若干堆,然后按照BABA...的顺序不断轮流取石头,能将剩下的石头一次取光的玩家获胜,每次取石头时,每个玩家只能从若干堆石头中任选一堆,取这一堆石头中任意数目(大于0)个石头。

请问:

玩家A要怎样分配和取石头才能保证自己有把握取胜?

如果石头的个数N为偶数,A只要将其分为相同的两份,就一定能取胜。

初始:XOR(M1, M1) == 0

玩家B:XOR(M1, M2) != 0  (其中一堆的个数减少到M2)

玩家A:XOR(M2, M2) == 0  (玩家A将另一堆的个数也减少到M2)

结果:XOR(M2, M2) == 0  (直到结束状态(0, 0))

如果石头的个数N为奇数,B有必胜的方法。

初始:XOR(M1, M2, ... , Mn) != 0

玩家B:XOR(M1, ... , Mi', ... , Mn) == 0 (其中一堆Mi的个数减少到Mi')

玩家A:XOR(M1, ... , Mj', ... , Mn) != 0

玩家B:XOR(M1, ... , Mi', ... , Mn) == 0 (其中一堆Mi的个数减少到Mi')

结果:XOR(M1, ... , Mj' , ... , Mn) == 0 (直到结束状态(0,0))

这里就有个问题:已知XOR(M1, M2, ... , Mn) != 0,玩家B该改变那个Mi以使得XOR(M1, ... , Mi', ... , Mn) == 0呢?

对于这个问题的答案,书中并未准确的结论。

经过本人的分析,所得到的结论如下:

设k=XOR(M1, M2, ... , Mn),已知k!=0,取一个数Mi,其二进制表达中在k的最高二进制位上的数为1,且这个

数Mi肯定存在(k的这个最高位在异或运算中肯定来自某一个Mi)。在程序中满足(Mi&k) > (k>>1)条件的数即为Mi。

简单证明:即假设k的二进制表达是1xx,那么Mi的二进制表达是x...x1xx,这样玩家B将该Mi改成Xi'=XOR(Mi, k)后,

Mi'的二进制表达是x...x0yy,肯定小于Mi,并且有XOR(M1, ... , Mi', ... , Mn) == 0。

参考: http://blog.csdn.net/linyunzju/article/details/7661060

1.13 NIM(3) 游戏

问题:

假设有两堆石头,有两个玩家会根据如下的规则轮流取石头:

每人每次可以从两堆石头中各取出数量相等的石头,或者仅从一堆石头中取出

任意数量的石头;最后把剩下的石头一次拿光的人获胜。请问在哪些局面(依

据两堆石头中的石头个数)下,先取石头的玩家有必胜的策略。

解法:

类似构造质数的筛选方法,这里我们利用找到的必输局面(后取的玩家有必胜策略)

来筛去掉能通过一次操作达该必输局面的其它必胜局面(先取的玩家有必胜策略)。

最后选出的局面都是必输局面。

构造必胜策略:

如果一开始的局面就是必输局面,那么可能先取的玩家没有必胜策略(当然如果后取

的玩家不太聪明,先取的玩家依然有可能能赢)。如果一开始的局面不是必输局面,

那么先取的玩家一定有必胜策略,且必胜策略就是保证每次都将当前非必输局面转变

为必输局面(后取的玩家必输)。

参考:http://blog.csdn.net/linyunzju/article/details/7674596

1.15 构造数独

问题:

构造一个9*9的方格矩阵,玩家要在每个方格中,分别填上1至9的任意一个数字,
让整个棋盘每一列、每一行以及每一个3*3的小矩阵中的数字都不重复。

首先我们通过一个深度优先搜索来生成一个可行解,然后随机删除一定数量的数字,
以生成一个数独。

参考: http://blog.csdn.net/linyunzju/article/details/7673959

1.16 24点游戏

问题:

给玩家4张牌,每张牌的面值在1-13之间,允许其中有数值相同的牌,采用加、减、乘、除四则运算,允许中间运算存在小数,并且可以使用括号,但每张牌只能用一次。构造表达式,使其结果为24.

解法:

传统的枚举解法会产生大量重复的运算,主要有两类重复:运算结果的重复和排列的重复。假设4张牌为3 3 8 8,我们对3 3进行一次操作(6种运算)得到6 0 0 1 1 9,其中重复的数据就是我们所说的运算结果重复,使用集合不重复性来解决。枚举算法在枚举时要对牌的顺序进行排列,由于牌可以重复,所以产生的排列会有大量的重复(3 3) 8 8, (3 8) 3 8, (3 8) 3 8, (3 8) 3 8,(3 8) 3 8, (8 8) 3 3,这属于排列重复,使用分治法加memo来解决。采用二进制数来表达集合和子集的概念,我们可以用一个数来表示子集中拥有哪些元素,再用这个数作为索引来找出该集合运算后产生的结果集。

1.17 俄罗斯方块

问题:

让电脑自动下俄罗斯方块游戏。

解法:

对当前的积木块,枚举它旋转后的每一个形状从每一列落下的棋盘,将该棋盘和前一个棋盘进行对比,并打分,最后取得分最高的那个形状和那一列作为电脑的当前操作。(由于程序的输入数据比较多,我将其和代码打包放在资源下载中,需要的读者可以去下载http://download.csdn.net/detail/linyunzju/4389102,鉴于有读者不会用这个程序,在此说明下,运行这个程序需要加上文件重定向<1_17.txt,或者把程序中的控制台输入scanf改成文件输入FILE* fin=fopen("1_17.txt"); fscanf(fin,"%d",...);)

代码:

参考:

http://blog.csdn.net/linyunzju/article/details/7686822

转载于:https://www.cnblogs.com/xkfz007/archive/2012/11/07/2758267.html

编程之美-第1章 游戏之乐相关推荐

  1. 第1章 游戏之乐——连连看游戏设计

    连连看游戏设计 连连看是一种很受大家欢迎的小游戏.微软亚洲研究院的实习生们就曾经开发过一个类似的游戏--Microsoft Link-up.    图1-17为Microsoft Link-up的一个 ...

  2. 编程之美中的NIM游戏及异或性质应用

    最近看<编程之美>一书,感叹思维之妙,不过看过之后又在很多数学方面的书里面找到了同样的解法例如<组合数学>.<图论导引>等,之后才知道其实很多书上的算法都是源自数学 ...

  3. 第1章 游戏之乐——构造数独

    构造数独 1. 问题 构造一个9*9的方格矩阵,玩家要在每个方格中,分别填上1至9的任意一个数字,让整个棋盘每一列.每一行以及每一个3*3的小矩阵中的数字都不重复. 2. 求解 用转置的方法生成数独数 ...

  4. 第1章 游戏之乐——快速找出故障机器

    转载:编程之美_1.5_快速找出机器故障 题目:假设一个机器只存储一个标号为ID的记录,假设每份数据保存2个备份,这样就有2个机器存储了相同的数据.其中ID是小于10亿的整数 问题1.在某个时间,如果 ...

  5. 【编程之美】24点游戏

    转自:http://blog.csdn.net/tianshuai1111/article/details/7713640 一,概述 二十四点是一种益智游戏,它能在游戏中锻炼人们的心算,它往往要求人们 ...

  6. 编程之美——4.11 扫雷游戏的概率

    http://blog.csdn.net/fivedoumi/article/details/7705073 题目说, 一局16×16的扫雷游戏刚开始, 只翻开了两格, 分别显示数字1和2, 如下图所 ...

  7. 编程之美-第3章 结构之法

    3.1. 字符串移位包含问题 方法1: 分别对字符串进行循环移1位,2位,3位-,来判断给定的字符串是否是其中一个字串. 复杂度是O(n^3) 方法2: 这也是一种利用空间换时间的方法. 代码如下, ...

  8. 2013编程之美资格赛【传话游戏】

    时间限制: 1000ms 内存限制: 256MB 描述 Alice和Bob还有其他几位好朋友在一起玩传话游戏.这个游戏是这样进行的:首先,所有游戏者按顺序站成一排,Alice站第一位,Bob站最后一位 ...

  9. 编程之美 set 17 拈游戏分析 (2)

    题目 有 N 块石头河两个玩家 A 和 B. A 先将石头分成若干堆, 然后按照 BABABA... 的顺序轮流取石块, 能将剩下的石头依次取光的玩家获胜. 每次取石头时, 每个玩家只能取一堆的 m( ...

最新文章

  1. [LeetCode] 102. Binary Tree Level Order Traversal_Medium tag: BFS
  2. 文字链接_新生命道目录及音频、文字链接(20200501更新)
  3. 什么?物联网方向也能发论文了?
  4. MSP430F5529 DriverLib 库函数学习笔记(八)模数转换模块(ADC12)
  5. postgresql 高可用 etcd + patroni 之六 callback bind vip
  6. 3.建造者模式(Builder)
  7. hadoop linux 集群提交任务
  8. 算法工程师面试备战笔记7_数据清洗与特征处理
  9. 计算机在线拍照解答,摄影景深在线计算器
  10. python+selenium常见坑
  11. 纬地道路纵断面设计教程_如何高效算量?市政道路从识图算量到施工工艺,一篇全搞定!...
  12. 自适应求积算法 MatLab版
  13. 如何清理卸下应用的残余文件_怎么清理手机卸载残留 需要技巧
  14. Python基础学习之 import 用法详解
  15. unity材质球发光_Unity3D - 发光材质(Emissive Materials)
  16. python_视频中语音识别转出文本
  17. GPS定位为什么需要4颗以上卫星?
  18. 开发类似斗鱼虎牙的运营级直播平台多少钱
  19. Post请求的两种编码格式:application/x-www-form-urlencoded和multipart/form-data
  20. 【PHP项目部署一】PHP环境配置

热门文章

  1. 上帝掷骰子:APP Store是赌场不是金矿
  2. 解决IntelliJIdea许可证过期,输入许可证认证不成功
  3. 技术教程 | 基于 Web 端的屏幕共享实践
  4. 某校2019专硕编程题-队列
  5. 【穿越百年咖啡厅Café logo,经典不败设计 】
  6. H5项目中通过iframe引入语音导览解决微信jsapi关于同一级域名二级域名跨域问题解决方案
  7. Hex文件和bin文件以及flash大小关系
  8. .msu格式文件跳过windowupdate检测直接安装方案(vs2015安装提示0x80240037安装失败,KB2999226无法安装)
  9. html5图片上传与预览实现
  10. e3服务器性能怎么样,3.5GHz发飙 至强E3-1280处理器深度评测