有趣的算法
① 一个有趣的算法问题。
很有趣,讨论一下吧:
先随机放个A,
将它的周围8个位置编号1,2,3,4,5,6,7,8
从1号到8号依次放楼,能放D就放D,不能就放C,C还不能就放B,
然后再以已放好的这九个为中心,放它周围的16个,
按相同的规则编号,然后放楼。
这样继续下去,直到放完。
如果碰到边界,也没关系,把除去边界部分编号处理。
这里有三个不确定的问题:
1、随机放和指定地方放,结果相同吗?
(可以调试测出)
2、先放A和先放B,C,D结果相同吗?
(也可以调试测出)
3、按这个路径扩展结果是不是最好的,还是按其他路径扩展会更好。
(找几条路径试试)
② 除了经典和常用的排序算法外,还有哪些奇葩而有趣的排序算法
排序算法有:
冒泡排序(bubble sort) — O(n^2)
鸡尾酒排序(Cocktail sort,双向的冒泡排序) — O(n^2)
插入排序(insertion sort)— O(n^2)
桶排序(bucket sort)— O(n); 需要 O(k) 额外空间
计数排序(counting sort) — O(n+k); 需要 O(n+k) 额外空间
合并排序(merge sort)— O(nlog n); 需要 O(n) 额外空间
原地合并排序— O(n^2)
二叉排序树排序 (Binary tree sort) — O(nlog n)期望时间; O(n^2)最坏时间; 需要 O(n) 额外空间
鸽巢排序(Pigeonhole sort) — O(n+k); 需要 O(k) 额外空间
基数排序(radix sort)— O(n·k); 需要 O(n) 额外空间
Gnome 排序— O(n^2)
图书馆排序— O(nlog n) with high probability,需要 (1+ε)n额外空间
不稳定的
选择排序(selection sort)— O(n^2)
希尔排序(shell sort)— O(nlog n) 如果使用最佳的现在版本
组合排序— O(nlog n)
堆排序(heapsort)— O(nlog n)
平滑排序— O(nlog n)
快速排序(quicksort)— O(nlog n) 期望时间,O(n^2) 最坏情况; 对于大的、乱数列表一般相信是最快的已知排序
Introsort— O(nlog n)
Patience sorting— O(nlog n+ k) 最坏情况时间,需要 额外的 O(n+ k) 空间,也需要找到最长的递增子串行(longest increasing subsequence)
不实用的
Bogo排序— O(n× n!) 期望时间,无穷的最坏情况。
Stupid sort— O(n^3); 递归版本需要 O(n^2) 额外存储器
珠排序(Bead sort) — O(n) or O(√n),但需要特别的硬件
Pancake sorting— O(n),但需要特别的硬件
stooge sort——O(n^2.7)很漂亮但是很耗时
③ 有哪些有趣而且神奇的按位运算
1) 判断int型变量a是奇数还是偶数
a&1 = 0 偶数
a&1 = 1 奇数
(2) 取int型变量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1 (先右移再与1)
(3) 将int型变量a的第k位清0,即a=a&~(1<<k) (10000 取反后为00001 )
(4) 将int型变量a的第k位置1,即a=a|(1<<k)
(5) int型变量循环左移k次,即a=a<<k|a>>16-k (设sizeof(int)=16)
(6) int型变量a循环右移k次,即a=a>>k|a<<16-k (设sizeof(int)=16)
(7)整数的平均值
对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的,我们用如下算法:
int average(int x, int y) //返回X、Y的平均值
{
return (x & y) + ( (x^y)>>1 );
}
(8)对于一个数 x >= 0,判断是不是2的幂。
boolean power2(int x)
{
return ( (x&(x-1))==0) && (x!=0);
}
(9)不用temp交换两个整数
void swap(int x , int y)
{
x ^= y;
y ^= x;
x ^= y;
}
(10)计算绝对值
int abs( int x )
{
int y ;
y = x >> 31 ;
return (x^y)-y ; //or: (x+y)^y
}
(11)取模运算转化成位运算 (在不产生溢出的情况下)
a % (2^n) 等价于 a & (2^n - 1)
(12)乘法运算转化成位运算 (在不产生溢出的情况下)
a * (2^n) 等价于 a<< n
(13)除法运算转化成位运算 (在不产生溢出的情况下)
a / (2^n) 等价于 a>> n
例: 12/8 == 12>>3
(14) a % 2 等价于 a & 1
(15) if (x == a)
x= b;
else
x= a;
等价于 x= a ^ b ^ x;
(16) x 的 相反数 表示为 (~x+1)
(17)输入2的n次方:1 << 19
(18)乘除2的倍数:千万不要用乘除法,非常拖效率。只要知道左移1位就是乘以2,右移1位就是除以2就行了。比如要算25 * 4,用25 << 2就好啦。
④ 有趣的数 求c语言代码及算法思路
php">functioncheck($data,$n){
$last0=0;
$first1=0;
$last2=0;
$first3=0;
$num=$data;
echo" ";
for($j=1;$j<=$n;$j++){
#code...
$a=floor($num/pow(10,$n-$j));
if($a>3){
return0;
}elseif(0==$a){
$last0=$j;
}elseif(1==$a){
$first1=(0==$first1)?$j:$first1;
}elseif(2==$a){
$last2=$j;
}elseif(3==$a){
$first3=(0==$first3)?$j:$first3;
}
$num=$num%pow(10,$n-$j);
echo"$a$last0,$first1,$last2,$first3$num ";
}
if($last0>$first1||$last2>$first3){
return0;
}
if(0==$last0||0==$first1||0==$last2||0==$first3){
return0;
}
return$data;
}
functiona($n){
$sum=0;
for($i=pow(10,$n-1);$i<pow(10,$n)-1;$i++){
#code...
$result=check($i,$n);
if(0!=$result){
#code...
$sum++;
// echo$i;
// echo" ";
// echo$result;
if(0==$sum%10){
echo" ";
}
}
}
echo$sum%1000000007;
}
PHP语言写的,没有C环境,就把变量名改改就能用
⑤ 哪位能给讲个有意思的算法,除了排序,查找
类似滴滴的最短路径算法,你可以用字体中的笔画顺序来给你提供模拟场景。
⑥ 一万加一万等于多少,有趣的算法
这中间有股票分割的部分,你没有计算上。比如你看到的某些60的股票,可能它的历史复权价已经高达十几万了,这部分数据我没统计过,只是给你做一个提醒。
⑦ 深度学习算法的哪些方面比较有趣
根据2012-2017年被引用最多的深度学习论文来看,深度学习目前的研究方向如下
1、基础性的理解和概括
2、优化训练
3、卷积神经网络模型研究
4、图像:分割/目标检测
5、视频
6、自然语言处理
7、强化学习/机器人
8、语音/其他领域
⑧ 求一个比较有意思的编程算法
*问题分析与算法设计
根据题意可以将解题过程分为三步:
1)计算从1990年1月1日开始至指定日期共有多少天;
2)由于“打鱼”和“晒网”的周期为5天,所以将计算出的天数用5去除;
3)根据余数判断他是在“打鱼”还是在“晒网”;
若 余数为1,2,3,则他是在“打鱼”
否则 是在“晒网”
在这三步中,关键是第一步。求从1990年1月1日至指定日期有多少天,要判断经历年份中是否有闰年,二月为29天,平年为28天。闰年的方法可以用伪语句
描述如下:
如果 ((年能被4除尽 且 不能被100除尽)或 能被400除尽)
则 该年是闰年;
否则 不是闰年。
C语言中判断能否整除可以使用求余运算(即求模)
*程序与程序注释
#include<stdio.h>
int days(struct date day);
struct date{
int year;
int month;
int day;
};
void main()
{
struct date today,term;
int yearday,year,day;
printf("Enter year/month/day:");
scanf("%d%d%d",&today.year,&today.month,&today.day); /*输入日期*/
term.month=12; /*设置变量的初始值:月*/
term.day=31; /*设置变量的初始值:日*/
for(yearday=0,year=1990;year<today.year;year++)
{
term.year=year;
yearday+=days(term); /*计算从1990年至指定年的前一年共有多少天*/
}
yearday+=days(today); /*加上指定年中到指定日期的天数*/
day=yearday%5; /*求余数*/
if(day>0&&day<4) printf("he was fishing at that day.\n"); /*打印结果*/
else printf("He was sleeping at that day.\n");
}
int days(struct date day)
{
static int day_tab[2][13]=
{{0,31,28,31,30,31,30,31,31,30,31,30,31,}, /*平均每月的天数*/
{0,31,29,31,30,31,30,31,31,30,31,30,31,},
};
int i,lp;
lp=day.year%4==0&&day.year%100!=0||day.year%400==0;
/*判定year为闰年还是平年,lp=0为平年,非0为闰年*/
for(i=1;i<day.month;i++) /*计算本年中自1月1日起的天数*/
day.day+=day_tab[lp][i];
return day.day;
}
*运行结果
Enter year/month/day:1991 10 25
He was fishing at day.
Enter year/month/day:1992 10 25
He was sleeping at day.
Enter year/month/day:1993 10 25
He was sleeping at day
⑨ 求几个有趣的算法,给高中生讲计算机入门用的
算法就用最简单的来讲呗。
最大公约数,最小公倍数。阶乘都不错!