(7)算法

树,图,查找,排序。数据结构学的差不多了可以尝试写点算法题了。

1.水仙花数

2.韩信点兵

3.倒三角形

4.子序列的和

5.分数化小数

6.排列

7.蛇形填数

8.WERTYU

9.生成元

10.全排列

11.最大公约数

12.杨辉三角

1.水仙花数:输出100999中的所有水仙花数。若3位数ABC满足ABCA3B3C3,则称其为水仙花数。例如153135333,所以153是水仙花数。

#include<stdio.h>
int main(){
	int a;
	int b;
	int c;
	int t;
	for(int i = 100;i<1000;i++){
		t = i;
		a = t/100;
		t = i-a*100;
		b = t/10;
		c = t-b*10;
		if(i==a*a*a+b*b*b+c*c*c){
			printf("%d\n",i);
		}
	}
}


1.韩信点兵:相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入包含多组数据,每组数据包含3个非负整数abc,表示每种队形排尾的人数(a3b5c7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100。输入到文件结束为止。

样例输入:

2 1 6

2 1 3

样例输出:

Case 1: 41

Case 2: No answer

#include<iostream>
using namespace std;
int main(){
	freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int a;
	int b;
	int c;
	bool flag = false;
	while(cin >>a>>b>>c){
	int q;
	int w;
	int e;
	flag = false;
	for(int i=10;i<=100;i++){
		q = i%3;
		w = i%5;
		e = i%7;
		if(q==a && w==b && e==c){
			cout<<i<<endl;
			flag = true;
			break;
		}
	}
	if(!flag){
		cout <<"No answer"<<endl;	
	}
	}
	fclose(stdin);
	//fclose(stdout);
}

3.倒三角形:输入正整数n20,输出一个n层的倒三角形。例如,n5时输出如下:

#########

 #######

  #####

   ###

    #


#include<iostream>
using namespace std;
void print(int a,int b){
	for(int i = 0;i<b;i++){
		cout << " ";	
	}
	for(int i = 0;i<a;i++){
		cout << "#";
	}
}
int main(){
	int t;
	cin >> t;
	int b = 0;
	int a = 2*t-1;
	while(a>=1){
		print(a,b);
		cout <<"\n";
		b++;
		a=a-2;
	}
}

4.子序列的和:输入两个正整数nm106,输出,保留5位小数。输入包含多组数据,结束标记为nm0

样例输入:

2 4

65536 655360

0 0

样例输出:

Case 1: 0.42361

Case 2: 0.00001

#include<iomanip>
using namespace std;
int main(){
	freopen("sbusequence.in.txt","r",stdin);
	int a;//用int第二组会溢出,改写表达式 
	int b;
	double s = 0;
	int t = 1;
	while(cin>>a>>b){
		s = 0.0;
		if(a==0 && b==0){
			return 0;
		}
		for(int i=a;i<=b;i++){
			s = s + 1.0/i/i;
		}
		cout <<"Case "<<t<<":"<<fixed<<setprecision(5)<<s<<endl;//fixed不使用科学计数法,setprecision设置精度 
		t++;
	}
	fclose(stdin);
}


5.分数化小数:输入正整数abc,输出a/b的小数形式,精确到小数点后c位。ab106c100。输入包含多组数据,结束标记为abc0

样例输入:

1 6 4

0 0 0

样例输出:

Case 1: 0.1667

#include<iostream>
#include<iomanip>
using namespace std;
int main(){
	freopen("decimal.in.txt","r",stdin);
	int a;
	int b;
	int c;
	int t;
	double s;
	int q=1;
	while(cin>>a>>b>>c){
		if(a==0 && b==0 && c==0){
			return 0;
		}
		s = a/(b+0.0);//转换为浮点数 
		cout <<"Case "<<q<<":"<<fixed<<setprecision(c)<<s<<"\n";
		q++;
	}
	fclose(stdin);
} 

6.排列:用123,…,9组成3个三位数abcdefghi,每个数字恰好使用一次,要

abcdefghi123。按照“abc def ghi”的格式输出所有解,每行一个解。


#include<iostream>
#include<iomanip>
using namespace std;
	int a;
	int b;
	int c;
	int q,w,e,r,t,y,u,i,o;
	int s[] = {0,0,0,0,0,0,0,0,0,0};
	int z;
bool fit(int num){
	a = num/1000000;
	b = num/1000%1000;
	c = num%1000;
	if(b == 2*a && c == 3*a){
		return true;
	}else{
		return false;
	}
}
int get(){
	return 0+
	+s[1]*100000000
	+s[2]*10000000
	+s[3]*1000000
	+s[4]*100000
	+s[5]*10000
	+s[6]*1000
	+s[7]*100
	+s[8]*10
	+s[9]*1;
}
int main(){
	for(int q=1;q<=9;q++){
		s[q] = 1;
		for(int w=1;w<=9;w++){
			if(s[w] == 0){
				s[w] = 2;
				for(int e=1;e<=9;e++){
					if(s[e] == 0){
						s[e] = 3;
						for(int r=1;r<=9;r++){
							if(s[r] == 0){
								s[r] = 4;
								for(int t=1;t<=9;t++){
									if(s[t] == 0){
										s[t] = 5;
										for(int y=1;y<=9;y++){
											if(s[y] == 0){
												s[y] = 6;
												for(int u=1;u<=9;u++){
													if(s[u] == 0){
														s[u] = 7;
														for(int i=1;i<=9;i++){
															if(s[i] == 0){
																s[i] = 8;
																for(int o=1;o<=9;o++){
																	if(s[o] == 0){
																		s[o] = 9;
																		z = get();
																		if(fit(z)) cout <<z<<"\n";
																		s[o] = 0;
																	}
																}
																s[i] = 0;
															}
														}
														s[u] = 0;
													}
												}
												s[y] = 0;
											}
										}
										s[t] = 0;
									}
								}
								s[r] = 0;
							}
						}
						s[e] = 0;
					}
				}
				s[w] = 0;
			}
		}
		s[q] = 0;
	}
}

虽然丑了点吧,但还是放出来当个纪念吧。。


7:蛇形填数。在n×n方阵里填入12,…,n×n,要求填成蛇形。例如,n4时方阵为:

10 11 12 1

9 16 13 2

8 15 14 3

7 6 5 4

#include<iostream>
#include<iomanip>
using namespace std;
enum Direction{
	Left,
	Right,
	Up,
	Down,
};
int main(){
	int a;
	cout <<"蛇形填数,阶数:";
	cin>>a;
	int num = a*a;
	int i = 1;
	int snake[a+1][a+1];
	for(int q=1;q<=a;q++){
		for(int w=1;w<=a;w++){
			snake[q][w] = 0;
		}
	}
	int hang = 1;
	int lie = a;
	Direction dir = Down;
	for(i=1;i<=num;i++){
		snake[hang][lie] = i;
		if(dir==Down){
			if(snake[hang+1][lie] == 0 && hang<a){
				hang++;
				continue;
			}else{
				if(snake[hang][lie-1] == 0 && lie>1){
					lie--;
					dir = Left;
					continue;
				}else{
					break;
				}
			}
		}
		
		if(dir==Left){
			if(snake[hang][lie-1] == 0 && lie>1){
				lie--;
				continue;
			}else{
				if(snake[hang-1][lie] == 0 && hang>1){
					hang--;
					dir = Up;
					continue;
				}else{
					break;
				}
			}
		}
		
		if(dir==Up){
			if(snake[hang-1][lie] == 0 && hang>1){
				hang--;
				continue;
			}else{
				if(snake[hang][lie+1] == 0 && lie<a){
					lie++;
					dir = Right;
					continue;
				}else{
					break;
				}
			}
		}
		
		if(dir==Right){
			if(snake[hang][lie+1] == 0 && dir<a){
				lie++;
				continue;
			}else{
				if(snake[hang+1][lie] == 0 && hang<a){
					hang++;
					dir = Down;
					continue;
				}else{
					break;
				}
			}
		}
		
	}
	for(int q=1;q<=a;q++){
		for(int w=1;w<=a;w++){
			cout <<snake[q][w]<<" ";
		}
		cout <<"\n";
	}
}

虽说我并没有考虑优化,但是刘大爷写成这样我也是服气的。

while(count<n*n){
        while(x+1<n && !a[x+1][y]) a[++x][y]=++count;//右下
        while(y-1>=0 &&!a[x][y-1]) a[x][--y]=++count;//向左
        while(x-1>=0 &&!a[x-1][y]) a[--x][y]=++count;//左上
        while(y+1<n &&!a[x][y+1])  a[x][++y]=++count;//向右
} 


8 WERTYU:把手放在键盘上时,稍不注意就会往右错一位。这样,输入Q会变成输入W,输入J会变成输入K等。输入一个错位后敲出的字符串(所有字母均大写),输出打字员本来想打出的句子。输入保证合法,即一定是错位之后的字符串。例如输入中不会出现大写字母A

样例输入:

O S, GOMR YPFSU/

样例输出:

I AM FINE TODAY.

#include<iostream>
#include<iomanip>
using namespace std;
int main(){
	freopen("UVa10082.in.txt","r",stdin);
	char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";//char数组就是字符串
	char a ;
	bool flag = false;
	while(true){
		a = cin.get();
		if(a != EOF){
			for(int i=0;i <47;i++){
				if(s[i] == a){
					cout <<s[i-1];
					flag = true;
				}
			}
			if(flag){
				flag=false;
				continue;
			}
			cout <<a;
		}else{
			break;
		}
	}
	fclose(stdin);
}

把可能性写出来再查表的思想非常好。下面一题就是这种思想的应用。

9 生成元:如果x加上x的各个数字之和得到y,就说xy的生成元。给出n1n100000),求最小生成元。无解输出0。例如,n=2161212005时的解分别为19801979

#include<iostream>
#include<iomanip>
using namespace std;
int main(){
	int s[100001];
	int a,b,c,d,e;
	int t;
	int num;
	for(int i=0;i<100001;i++){
		s[i] = 0;
	} 
	for(int i=1;i<100000;i++){
		a = i/10000;
		b = i/1000%10;
		c = i/100%10;
		d = i/10%10;
		e = i%10;
		t = i+a+b+c+d+e;
		if(s[t] == 0){
			s[t] = i;
		}
	}
	while(true){
		cin >>num;
		if(num==0) break;
		cout<<"最小生成元:" <<s[num]<<"\n";
	}
	return 0;
}

10:全排列:生成全排列

#include<iostream>
#include<iomanip>
using namespace std;
void print(int s[],int n){
	for(int i=1;i<=n;i++){
		cout << s[i];
	}
	cout <<"\n";
}
void per(int a,int n,int s[]){
	if(a>n){
		print(s,n);
	}else{
		for(int i=1;i<=n;i++){
			if(s[i] == 0){
				s[i] = a;
				per(a+1,n,s);
				s[i] = 0;
			}
		}
	}
}
int main(){
	int n;
	cin >> n;
	int s[n+1];
	for(int i=0;i<=n;i++){
		s[i] = 0;
	}
	per(1,n,s);
}

下面这个是改进后的版本,生成的数字有序

#include<iostream>
#include<iomanip>
using namespace std;
//通过辅助数组c查看哪个数还没有填 。对于可重集,只要c的数小于重复数,即可填写 
//1.参数准备
//2.调用递归
//3.边界检测和处理
//4.递归处理和调用 
//明显看出递归的效率不行,7的时候性能就不行了 
void print(int s[],int n){
	for(int i=1;i<=n;i++){
		cout << s[i];
	}
	cout <<"\n";
}
void per(int a,int n,int s[],int c[]){
	if(a>n){
		print(s,n);
	}else{
		for(int i=1;i<=n;i++){
			if(c[i] == 0){
				c[i] = 1;
				s[a] = i;
				per(a+1,n,s,c);
				c[i] = 0;
			}
		}
	}
}
int main(){
	int n;
	cin >> n;
	int s[n+1];
	int c[n+1];
	for(int i=0;i<=n;i++){
		s[i] = 0;
		c[i] = 0;
	}
	per(1,n,s,c);
}

11 最大公约数:

#include<iomanip>
using namespace std;
int main(){
	int a,b;
	cout<<"辗转相除法求最大公约数:\n";
	cout<<"a=";
	cin>>a;
	cout<<"b=";
	cin>>b;
	int c;
	if(a<=b){
		c=a;
		a=b;
		b=c;
	}
	while(b != 0){
		c = a%b;
		a=b;
		b=c;
	} 
	cout<<"最大公约数:"<<a;
}

以及递归版本:

int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}

12杨辉三角

杨辉三角用于生成二项式的系数

#include<iostream>
#include<iomanip>
using namespace std;
int main(){
	int a;
	cin >> a;
	int s[a+1][a+1];
	for(int i=0;i<=a;i++){
		for(int j=0;j<=a;j++){
			s[i][j] = 0;
		}
	}
	//输入对应次幂的杨辉三角
	s[0][0] = 1;
	s[1][0] = 1;
	s[1][1] = 1;
	for(int i=2;i<=a;i++){
		s[i][0]=1;
		for(int j=1;j<=a;j++){
			s[i][j] = s[i-1][j-1] + s[i-1][j];
		}
	} 
	for(int i=0;i<=a;i++){
		for(int j=0;j<=a;j++){
			if(s[i][j] !=0) cout <<" "<< s[i][j];
		}
		cout << "\n";
	}
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值