********************************************************************************
本文题目源自飞燕之家在线测评论坛http://yzfy.org/,程序由博主编写,转载清注明出处
********************************************************************************
基础算法题目精简集合
题目相对来说简要了一些,算是有代表性了,各方面都有题目,偶不希望像别的帖子那样像为了凑数般弄够100题,相反这里不过二三十。
前六章均为算法基础入门必会解答的题目,也就是若当中有任何一题,您无法给出正确解答,就不算有算法基础(带星的题目例外),并且这里不提供基础题解答,若你实在需要,请自行查资料或者找人帮你。
下文假定阅读者具有良好的小学数学基础,以及懂得使用C/C++/Pascal语言当中的任何一种,尽管你会其它的语言也行,但算法描述方面以及代码效率还是推荐以上三种。
如果以下算法基础的题目您学习了很久也无法正确解决的话,那么本人不建议你继续学习编程(基础题不用STL库独立解答出才算是会)。
第一章。循环控制
1.输入一个奇数n,输出对角线长为n的实心或者空心的菱形图案
如当n=5时,有:
*
***
*****
***
*
实现代码:
Code
1 #include <stdio.h>
2
3 int main()
4 {
5 int n,i,j;
6 scanf("%d",&n);
7 for(i=1;i<=n/2+1;i++)
8 {
9 for(j=1;j<=(n-2*i+1)/2;j++)
10 printf(" ");
11 for(j=1;j<=2*i-1;j++)
12 printf("*");
13 for(j=1;j<=(n-2*i+1)/2;j++)
14 printf(" ");
15 printf("\n");
16 }
17 for(i=1;i<=n/2;i++)
18 {
19 for(j=1;j<=i;j++)
20 printf(" ");
21 for(j=1;j<=n-2*i;j++)
22 printf("*");
23 for(j=1;j<=i;j++)
24 printf(" ");
25 printf("\n");
26 }
27 return 0;
28 }
29
2.输入一个奇数n,构造并输出一个n阶等和幻方,
即每一行每一列和两对角线上的n个数的和相等
如当n=5时,有(构造方法请自行搜索或者观察下表):
03 16 09 22 15
20 08 21 14 02
07 25 13 01 19
24 12 05 18 06
11 04 17 10 23
Code
1 #include <stdio.h>
2
3
4 void Magic(int n)
5 {
6 int m[15][15];
7 int i,j,p;
8 p=1;
9 for(i=0;i<n;i++)
10 for(j=0;j<n;j++)
11 m[i][j]=0;
12 i=0;j=n/2;
13 while(p<=n*n)
14 {
15 m[i][j]=p++;
16
17
18 if(i==0&&j<(n-1)&&j>=0)//走到第一行非右上角时
19 {
20
21 if(0==m[n-1][j+1])
22 {
23 i=n-1;j=j+1;
24 }
25 else
26 i=i+1;
27 }
28 else if(i>0&&i<(n-1)&&j==(n-1))//走到最右端非右上角和右下角时
29 {
30
31 if(0==m[i-1][0])
32 {
33 i=i-1;j=0;
34 }
35 else
36 i=i+1;
37 }
38 else if(i==(n-1)&&j>=0&&j<(n-1))//走到最后一排非右下角时
39 {
40
41 if(0==m[i-1][j+1])
42 {
43 i=i-1;j=j+1;
44 }
45 else
46 i=0;
47
48
49 }
50 else if(i==0&&(n-1)==j)//走到右上角时
51 {
52
53 if(0==m[n-1][0])
54 {
55 i=n-1;j=0;
56 }
57 else
58 i=i+1;
59
60 }
61 else if(i==(n-1)&&j==(n-1))//走到右下角时
62 {
63
64 if (0==m[n-2][0])
65 {
66 i=n-2;j=0;
67
68 }
69 else
70 i=0;
71
72 }
73 else//其它情况
74 {
75 if(0==m[i-1][j+1])
76 {
77 i=i-1;j=j+1;
78 }
79 else
80 i=i+1;
81 }
82 }
83
84 for(i=0;i<n;i++)
85 {
86 for(j=0;j<n;j++)
87 printf("%3d ",m[i][j]);
88 printf("\n");
89 }
90
91 }
92
93 int main(void)
94 {
95 int n;
96 scanf("%d",&n);
97 Magic(n);
98
99 return 0;
100 }
101
3.输入一个1e9以内的整数n和k(2<=k<=36),输出相应的k进制数。
Code
1 #include<stdio.h>
2 int NumConvert(int n,int k)
3 {
4 int t = n;
5 char buf[100];
6 int i,j;
7 for(i=0;i<100 && t>0;i++,t/=k)
8 {
9 j = t % k;
10 if(j < 10) buf[i]= '0'+j;
11 else buf[i] = 'A'-10+j;
12 }
13 for(;i>0;) printf("%c",buf[--i]);
14 return 0;
15 }
16
17 int main()
18 {
19 int n,k;
20 scanf("%d,%d",&n,&k);
21 NumConvert(n,k);
22 return 0;
23 }
4.输入一个整数n(2<=n<=1e9),判断它是不是质数,
时间复杂度必须为O(n^0.5),不得为O(n)
质数就是2,以及其它有且只有两个约数的整数,
如3,5,7,11,13,17,19,23,29,31,......(以上为前10个奇质数)
Code
#include <stdio.h>
int main()
{
int m,i,k;
scanf("%d,&m");
k=sqrt(m+1);
for(i=2;i<=k;i++)
if(m%i==0)
break;
if(i>=k+1)printf("%d is a prime muber\n",m);
else printf("%d is not a prime muber\n",m);
return 0;
}
5.字符串模式匹配。输入两个字符串a,b,判断b是否在a中出现,
如有,请输出第一次出现的位置。
Code
1 #include <stdio.h>
2 #include <string.h>
3
4 void StrFind(char * a,char *str)
5 {
6 char *p;
7 int lenStr=strlen(str);
8 int lenA=strlen(a);
9 int k=lenA-lenStr;
10 int i;
11 int j;
12
13 for(p=a,i=1;p<=a+k;p++,i++)
14 {
15 j=0;
16 while(j<lenStr)
17 {
18
19 if(*(p+j)!=*(str+j))
20 break;
21 j++;
22 }
23 if('\0'==*(str+j))
24 {
25 printf("The fahter string has the son string,the position is %d\n",i);
26 break;
27 }
28 }
29 }
30
31 int main()
32 {
33 char fathStr[100],sonStr[50];
34 scanf("%s %s",fathStr,sonStr);
35 StrFind(fathStr,sonStr);
36
37 return 0;
38 }
第二章。简单穷举搜索
1.输入两个数a,b(1 <= a,b <= 1e5),统计a,b之间一共有多少个质数
相关题目请参阅http://yzfy.org/bbs/viewthread.php?tid=392
若要通过链接里那个题目还需要优化,单纯做出本题并不难。
如何优化?
Code
1 #include <iostream>
2 #include <math.h>
3 using namespace std;
4
5 bool IsPrime(int n)
6 {
7 int k;
8 if(n<2)
9 return false;
10 for(k=2;k<=sqrt((double)n);k++)
11 if(0==n%k)
12 return false;
13 return true;
14 }
15
16 int main()
17 {
18 int a,b,count=0;
19 cin>>a>>b;
20 for(int i=a;i<=b;i++)
21 {
22 if(IsPrime(i))
23 ++count;
24 }
25 cout<<"The count of prime numbers between a and b is "<<count<<endl;
26 return 0;
27
28 }
2.查找1000以内的所有水仙花数,如153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27
各位上的数字的三次方的和等于自己本身
Code
1 #include <iostream>
2 using namespace std;
3
4 bool IsShuixianNum(int n)
5 {
6 int a,b,c;
7 a=b=c=0;
8 a=n/100;
9 c=n%10;
10 b=(n-100*a)/10;
11 if(n==a*a*a+b*b*b+c*c*c)
12 return true;
13 else
14 return false;
15 }
16
17 int main()
18 {
19 int i,count=0;
20 for(i=10;i<1000;i++)
21 if(IsShuixianNum(i))
22 {
23 ++count;
24 cout<<i<<endl;
25 }
26 cout<<"the count of Shuixian number is "<<count<<endl;
27 return 0;
28 }
3.输入一个数n(1<=n<=1e4),然后再输入n个不同的整数,再输入一个整数k,
判断k是否在那n个整数上出现过。
Code
1 #include <iostream>
2 using namespace std;
3
4 int main()
5 {
6 int n,i=0;
7 int j,k;
8 int a[10000];
9 cout<<"please input the count of numbers"<<endl;
10 cin>>n;
11 cout<<"please input n different numbers"<<endl;
12 while(i<n)
13 {
14 cin>>a[i];
15 for(j=0;j<i;j++)//保证输入的数字不重复
16 if(a[j]==a[i])
17 {
18 cout<<"the number is illegal,please input another number!"<<endl;
19 break;//重复则退出
20 }
21 if(j>=i)
22 i++;
23 }
24 cout<<"please input k"<<endl;
25 cin>>k;
26 for(i=0;i<n;i++)
27 {
28 if(k==a[i])
29 {
30 cout<<"k is the "<<i+1<<"th number of the "<<n<<" numbers"<<endl;
31 break;
32 }
33 }
34 if(i>=n)
35 cout<<"k is not in the "<<n<<" numbers"<<endl;
36
37 return 0;
38 }
第三章。迭代、递推和递归
1.斐波那契数列和:输入整数n,求1/1+2/1+3/2+5/3+8/5+.....
一直到第n项的结果。
Code
1 #include <iostream>
2 using namespace std;
3
4 int main()
5 {
6 long int f1,f2;
7 int i,a,n;
8 cin>>n;
9 if(1==n)
10 cout<<"1"<<endl;
11 else if(2==n)
12 cout<<"3"<<endl;
13 else
14 {
15 f1=2;
16 f2=1;
17 float m,sum=3;
18 for(i=3;i<=n;i++)
19 {
20 a=f1;
21 f1=f1+f2;
22 f2=a;
23 sum+=(float)(f1)/f2;
24 }
25 cout<<sum<<endl;
26 }
27 return 0;
28 }
2.★经典Hanoi塔问题。
Code
1 //分析:
2 //将n个盘子从A针移到C针可以分解为下面3个步骤:
3 //1.将A上n-1个盘子移动到B针(借助C针)
4 //2.将A剩下的一个盘子移动到C针
5 //3.将n-1个盘子从B针移动到C针
6 //以上三个步骤都包括以下两种操作:
7 //1.将多个盘子移动到另一针上,利用递归
8 //2.将一个盘子移动到另一针上
9 //于是程序就可以如下编写:
10 #include <iostream>
11 using namespace std;
12
13 void move(char getone,char putone)
14 {
15 cout<<getone<<" --> "<<putone<<endl;//将一个盘子移动到另一针上
16 }
17
18 //将多个盘子移动到另一针上,利用递归
19 void hanoi(int n,char one,char two,char three)
20 {
21 void move(char getone,char putone);
22 if(1==n) move(one,three);
23 else //将多个盘子移动从A针移动到C针的步骤
24 {
25 hanoi(n-1,one,three,two);//将A上n-1个盘子移动到B针(借助C针)
26 move(one,three);//将A剩下的一个盘子移动到C针
27 hanoi(n-1,two,one,three);//将n-1个盘子从B针移动到C针
28 }
29 }
30 int main()
31 {
32 void hanoi(int n,char one,char two,char three);
33 int m;
34 cout<<"Enter the number of diskes:";
35 cin>>m;
36 cout<<"the steps to moving "<<m<<" diskes:"<<endl;
37 hanoi(m,'A','B','C');
38 return 0;
39 }
第四章。简单计算几何
1.简单碰撞检测
编写一个函数
int IsOnRECT(float x, float y, float r,float x1, float y1, float x2, float y2)
x,y表示一个圆的圆心,r是圆的半径,x1,y1,x2,y2表示一个矩形的一条对角线上的两个顶点的坐标矩形的四边均与坐标轴平行或者垂直,要判断这个圆和这个矩形有没有重合的部分。
输入:
按照参数传递进行输入,样例中一行就是一次输入
按顺序分别对应x,y,d,x1, ....
输出:
使用函数返回值作为输出,当有重合的时候返回非0,否则请返回0
函数中不得含有任何其它输出,否则作为错误
样例输入:
1 1 1 0 0 2 2
1 1 1 2 2 3 3
样例输出:
1
0
其它:
答题时请不要粘贴上main函数,需要任何头文件请自己包含因精度方面问题,不需要考虑相切,相切作为不重合处理即可。
Code
1 #include <iostream>
2 using namespace std;
3
4 int IsOnRECT(float x, float y, float r, float x1, float y1, float x2, float y2)
5 {
6 float p,q;
7 if(x1 > x2){p=x1,x1=x2,x2=p;}
8 if(y1 > y2){p=y1,y1=y2,y2=p;}
9 p = x;
10 if(x1 > p) p = x1;
11 if(x2 < p) p = x2;
12 q = y;
13 if(y1 > q) q = y1;
14 if(y2 < q) q = y2;
15 return (p-x)*(p-x)+(q-y)*(q-y)<r*r ? 1 : 0;
16 }
17
18 int main()
19 {
20 float x,y,r,x1,y1,x2,y2;
21 cin>>x>>y>>r;
22 cin>>x1>>y1>>x2>>y2;
23 if(IsOnRECT(x,y,r,x1,y1,x2,y2))
24 cout<<"The circle and the rectangle crashed"<<endl;
25 else
26 cout<<"The circle and the rectangle didn't crashed"<<endl;
27
28 }