翻滚吧牛牛(一)
牛牛有一个边长为1的正六边形,只要牛牛一推它就可以一直滚下去,正六边形左下角为A,牛牛想知道正六边形翻滚k次A点的轨迹边长是多少呢。如图是正六边形翻滚一次的情况。给定正六边形翻滚次数k,求A点翻滚轨迹长度
第一次旋转 πr/3,第二次旋转 √3πr/3,第三次旋转 2πr/3...以此类推
class Solution {public: /** * * @param k int整型 翻滚次数 * @return double浮点型 */ double circumference(int k) { double r[5]={1,sqrt(3),2,sqrt(3),1}; double l=0; for(int i=0;i<k;i++) { l+=r[i%6]*acos(-1)/3.0; } return l; } };
牛牛的分配
在牛牛面前有nnn个瓶子,每个瓶子的大小体积都一样,但是每个瓶子内的含水量都不相同。
因为牛牛是个完美主义者,他希望瓶子中的水能够满足他的要求,他的要求是瓶子中的水最少为xxx。所以他打算对这些瓶子里的水进行重新分配,以满足最多的瓶子中水量大于等于xxx。
牛牛的分配规则是:每次可以选择多个瓶子,将里面的水平均分配到已选择的瓶子中。
给定nnn个瓶子和牛牛的对瓶中的水量要求xxx,以及nnn个瓶子中的含水量,求最多可以有多少个瓶子满足牛牛的要求?
思路
把原来的vector排个序,从大到小看,如果当前的水瓶中的水量大于x,s++,并且将多余的水分给下一个水瓶。
class Solution {public: /** * 返回重新分配后,满足牛牛要求的水量的瓶子最多的数量 * @param n int整型 瓶子的数量 * @param x int整型 牛牛的对瓶中的水量要求 * @param a int整型vector 每个瓶子中的含水量 * @return int整型 */ int solve(int n,int x,vector<int> &a) { sort(a.begin(),a.end()); int i,s=0; for(i=a.size()-1;i>0;i--) { if(a[i]>=x) { s++; a[i-1]+=a[i]-x; } } if(a[0]>=x) s++; return s; } };
牛牛构造等差数列
牛牛和牛妹在玩一个游戏,在他们面前有n个数,他们对每个数可以进行 +1 或 -1 操作,但对于每一个数,该操作最多只能执行一次。
游戏胜利的目标是:使用最少的操作次数,将这几个数构造成一个等差数列。
牛牛特别想赢得游戏,所以他想让你帮他写一个程序,得出最少多少次操作后能使这几个数变成一个等差数列,当然,如果完全不能构造成功,就输出-1。
class Solution {public: /** * 返回最少多少次操作后能使这几个数变成一个等差数列,如果完全不能构造成功,就返回-1 * @param n int整型 代表一共有n个数字 * @param b int整型vector 代表这n个数字的大小 * @return int整型 */int solve(int n, vector<int>& b) { if(n<=2) return 0; int s=0x7fffffff; for(int i=-1;i<=1;i++) { for(int j=-1;j<=1;j++) { int first=b[0]+i; int second=b[1]+j; int d=first-second; int now=second; int cnt=abs(i)+abs(j); for(int k=2;k<n;k++) { now-=d; if(abs(now-b[k])<=1) cnt+=abs(now-b[k]); else break; if(k==n-1) s=min(cnt,s); } } } if(s<0x7fffffff) return s; return -1; } };
playfair
牛牛想给牛妹写信,但是牛牛怕信中的信息泄露出去,于是用playfair加密信息。加密过程中的j都由i来代替。playfair加密算法首先需要绘制密码表,密码表是一个5*5的矩阵,开始由密钥按顺序排列,其余按照未出现的字母顺序。若密钥中含有重复字母需要将重复字母去掉,若有j用i来代替,例如密钥为nowcoder,得到的密码表为
加密明文需要符合以下规则:
现在牛牛告诉你密钥和明文你能告诉牛牛密文是什么吗?