约瑟夫环问题:每次从这个圆圈中删除第 m 个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第 m 个数字。求出在这个圆圈中剩下的最后一个数字。
据说之前,这些数字是死囚,能抽到最后一个的人能活着……
模拟的方法弱爆了,有递推公式的,假设有n个人,每轮第k个人被杀掉,递推公式如下:
如果想知道推导过程,可以看维基百科:"Josephus problem"
即初始sum=0,我们从i=2开始(i就是上面公式的[......]
约瑟夫环问题:每次从这个圆圈中删除第 m 个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第 m 个数字。求出在这个圆圈中剩下的最后一个数字。
据说之前,这些数字是死囚,能抽到最后一个的人能活着……
模拟的方法弱爆了,有递推公式的,假设有n个人,每轮第k个人被杀掉,递推公式如下:
如果想知道推导过程,可以看维基百科:"Josephus problem"
即初始sum=0,我们从i=2开始(i就是上面公式的[......]
原题是编程之美上的,数组无序。书上面的最优解法是先排序。。。所以有了这道题。
前提是有序,所以可以用O(n)解决。
即begin和end两个下标,往中间凑。如果sum满足输出。
如果大于目标,end--;
如果小于目标,begin++;
void sum_print(int* arr, int n, int sum)
{
int i, j;
for(i=0,j=n-1;i<j && i>=0 && j<n; )[......]
题目:输入一个单向链表,输出该链表中倒数第 k 个结点。
传统做法是获取到链表的长度n,然后走n-k布,此方法弱爆了……
做法:
1、指定一个新的指针,走k步。如果k布之内就到了NULL,显然无倒数第k这说法,返回错误即可。
2、新指针到位后,和root一起next,知道新指针到了NULL。此时输出root指针当前的data即可。
int ll_last_k(struct Node* root, int k)
{
// Make two ptr diff k di[......]
树的计数问题:具有n个结点的不同形态的树共有多少棵。即具有n个结点、互不相似的二叉树的数目bn。
二叉树的相似:两棵都为空树或者两棵都不是空树,而且它们的左右子树分别相似。
二叉树的等价:两者不仅相似,而且对应结点上的元素均相同。
二叉树在bn较小的时候形态和计数如下:
经过书上复杂的推导,含有n个结点的互不相似的二叉树个数为:
如果推广一下,不是二叉树而是树,则:
具有n个结点的互不相似的树的个数为tn = bn-1
即:
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。
例如输入“I am a student.”,则输出“student. a am I”。
这种题是很无聊的,而且用istream什么就没有可以做的了,思路:倒着遍历字符串,查找到一个空格后,输出本空格与上次空格之间的内容。可以用\0临时替代printf。
代码如下:
#include <stdio.h>
#include <[......]