C语言经典编程实例(六)

文章目录

          • 一、C语言基础
            •  1.判断三角形的类型
            •  2.矩阵转置
            •  3.求自然底数e
            •  4.回文素数
            •  5.圆周率π
            •  6.完全数
            •  7.亲密数
            •  8.自守数
            •  9.回文数
            •  10.勾股数

使用C++语言解决C语言常见重点、要点问题


一、C语言基础
 1.判断三角形的类型

  根据输入的三角形的三条边判断三角形的类型,并输出其面积和类型。

首先处理输入数据的合法性,即若两边之和大于第三边即可考虑下一步操作,若小于则不能构成三角形,之后利用海伦公式计算面积并判断其类型。判断类型时若三边相等则为等边三角形,若两边相等则为等腰三角形,若两边的平方和等于第三边的平方和则为直角三角形,否则为普通三角形。

int main()
{
	float l = 0, w = 0, h = 0;
	float aver = 0, area = 0.0;

	cout << "Please enter the three sides of the triangle: ";
	cin >> l >> w >> h;

	if (l + w > h && l + h >= w && h + w > l)
	{
		aver = (l + w + h) / 2;
		area = (float)sqrt(aver*(aver - l)*(aver - w) * (aver - h));
		cout << "The Area of triangle is: " << area << endl;

		if (l == w && l == h)
			cout << "Is Equilateral triangle" << endl;
		else if (l == w || l == h || w == h)
			cout << "Is Isosceles triangle" << endl;
		else if ((l * l + w * w == h * h) || (l * l + h * h == w * w)
			|| (w * w + h * h == l * l))
			cout << "Is Right triangle" << endl;
		else
			cout << "Is Normal triangle" << endl;
	}
	else
	{
		cout << "Data Error!" << endl;
	}

	system("pause");
	return 0;
}
 2.矩阵转置

  设有一矩阵为 m×n 阶(即 m 行 n 列),第 i 行 j 列的元素是 a(i,j),需要将该矩阵转置为 n×m 阶的矩阵,使其中元素满足 b(j,i)=a(i,j)

考虑矩阵转置,根据数学知识可知,将原始矩阵的的所有元素绕着一条从第一行第一列出发的右下角45° 的射线做镜面反转,即可得到矩阵的转置

int main()
{
	int rows = 0, cols = 0;
	cout << "please input the number of rows: ";
	cin >> rows;
	cout << "please input the number of cols: ";
	cin >> cols;
	cout << "please input the element: ";

	vector<vector<int>> Array(rows);
	for (int i = 0; i < rows; ++i)
	{
		for(int j = 0;j < cols;++j)\
		{
			int in = 0;
			cin >> in;
			Array[i].push_back(in);
		}
	}
	vector<vector<int>> New_Array(cols,vector<int>(rows));

	for (int i = 0; i < rows; ++i)
	{
		for (int j = 0; j < cols; ++j)
		{
			New_Array[j][i] = Array[i][j];
		}
	}

	for (int i = 0; i < cols; i++)
	{
		for (int j = 0; j < rows; j++)
			cout << New_Array[i][j] << ' ';

		cout << endl;
	}

	system("pause");
	return 0;
}
 3.求自然底数e

  自然底数 e=2.718281828…

e 的计算公式:e=1+1/1!+1/2!+1/3!+…,要求当最后一项的值小于 10^10 时结束

int main()
{
	float e = 1.0;
	float tmp = 1.0;
	int i = 1;

	while (1/tmp > 1e-10) 
	{
		e += 1 / tmp;
		i++;
		tmp *= i;
	}

	cout << "The value if e is: " << e << endl;
	system("pause");
	return 0;
}
 4.回文素数

  任意的整数,当从左向右读与从右向左读是相同的,且为素数时,称为回文素数。求 1000 以内的所有回文素数

素数(质数):大于1的自然数中除了1和本身之外不再有其他因数的数称为素数,其余称为合数;回文素数:任意的素数从左向右读和从右向左读相同称为回文素数。

bool IsPrime(int number)
{
	bool isPrime = true;
	int k = (int)sqrt((double)number);

	for (int i = 2; i <= k; i++)
	{
		if (number % i == 0)
		{
			isPrime = false;
			break;
		}
	}

	return isPrime;
}

int main()
{
	int num = 1;

	cout << "The number of prime texts in 1 ~ 1000 is: ";

	for (num = 10; num < 1000; num++)
	{
		if (IsPrime(num))
		{
			if (num / 100 == 0)//判断是否是三位数
			{
				if (num / 10 == num % 10)
				{
					cout << "  " << num;
				}
				if (num % 5 == 0)
					cout << endl;
			}
			else
			{
				if (num / 100 == num % 10)
					cout << "  " << num;
				if (num % 5 == 0)
					cout << endl;
			}
		}
	}
	cout << endl;
	system("pause");
	return 0;
}
 5.圆周率π

   求圆周率π的值

先计算π/4的值,然后再乘以4,s=-s; 用的很巧妙,每次循环,取反,结果就是,这次是正号,下次就是负号,以此类推

int main()
{
	float s = 1;
	float pi = 0;
	float i = 1.0;
	float n = 1.0;

	while (fabs(i) >= 1e-6)
	{
		pi += i;
		n += 2;
		s = -s;
		i = s / n;
	}

	pi = 4 * pi;
	cout << "The value of the π is: " << pi << endl;

	system("pause");
	return 0;
}
 6.完全数

   求某一范围内完数的个数

如果一个数等于它的因子之和,则称该数为“完数”(或“完全数”)。例如,6的因子为1、2、3,而 6=1+2+3,因此6是“完数”
对于某一整数来说,其最大因子为n/2 (n为偶数时,若为奇数,最大因子小于n/2),在n/2〜n-1范围内没有数据可以整除此数。据此,我们可以把遍历范围从1~i-1缩小至1〜i/2,这样程序效率可以提高一倍

int main()
{
	int sum = 0;
	int num = 0;

	cout << "Please input a number: ";
	cin >> num;

	cout << "The perfect number is: ";
	for (int i = 2; i <= num; i++)
	{
		sum = 0;
		for (int j = 1; j < i; ++j)
		{
			if (i % j == 0)
				sum += j;
		}
		//for (int j = 1; j <= (i / 2); ++j)
		//{
		//	if (i % j == 0)
		//		sum += j;
		//}

		if (sum == i)
			cout << ' ' << i;
	}

	cout << endl;
	system("pause");
	return 0;
}
 7.亲密数

   如果整数A的全部因子(包括1,不包括A本身)之和等于B;且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。求3000以内的全部亲密数

穷举法

int main()
{
	cout << "There are following friendly--numbers pair smaller than 3000: ";

	for (int i = 1; i < 3000; ++i)//该范围内的亲密数
	{
		int val1 = 0;
		for (int j = 1; j <= i / 2; ++j)
		{
			if (i % j == 0)
				val1 += j;
		}//某一数的因子之和

		int val2 = 0;
		for (int j = 1; j <= val1 / 2; ++j)
		{
			if (val1 % j == 0)
				val2 += j;
		}//上步计算出的和的因子之和

		if (val2 == i && i < val1)
			cout << ' ' << i << "--" << val1;
	}

	cout << endl;
	system("pause");
	return 0;
}
 8.自守数

   自守数是指一个数的平方的尾数等于该数自身的自然数。例如:52 = 25 252 = 625 762 = 5776 93762 = 87909376,求100000以内的自守数。

根据自守数的定义,首先需要知道当前自守数的位数以及该数平方的尾数与被乘数,乘数之间的关系。
若采用求出一个数的平方后再截取最后相应位数的方法不可取,因为计算机无法表示过大的整数
因此从整数平方的计算过程总结规律
     3 7 6 被乘数
    × 3 7 6 乘数
—————————————
    2 2 5 6   第一个部分积 = 被乘数 × 乘数的倒数第一位
   2 6 3 2    第二个部分积 = 被乘数 × 乘数的倒数第二位
  1 1 2 8     第三个部分积 = 被乘数 × 乘数的倒数第三位
—————————————
  1 4 1 3 7 6   积
例子中关心的是积的后三位,分析过程可以看到在三位数的乘法中,对积的后三位产生影响的是:

  • 第一个部分积中:被乘数最后三位 x 乘数的倒数第一位
  • 第二个部分积中:被乘数最后两位 x 乘数的倒数第二位
  • 第三个部分积中:被乘数最后一位 x 乘数的倒数第三位

将以上部分积的后三位求和即可得到三位数乘积的后三位
故从一个两位数(存在于变量n中)开始分析,分析最低个位n%10;对于三位数,分离最后两位n%100;对于四位数,分离最后三位n%1000;······,所以荣分离出最后x位,需要用原数对10x 求余
上述例子中,第二个部分积“2632”实质应该是“26320”,因为乘数中的倒数第二位“7”的权值是10,故376 x 70 = 26320

int main()
{
	long mul = 0;
	long k, a, b;
	cout << "It exists following automorphic nmbers small than 100000: ";

	for (long number = 0; number < 100000; ++number)
	{
		for (mul = number, k = 1; (mul /= 10) > 0; k *= 10);//由number的位数确定截取数字进行乘法时的系数k

		a = k * 10;//截取部分积时的系数
		mul = 0;//积的最后n位
		b = 10;//截取乘数相应位时的系数

		while (k > 0)
		{
			mul = (mul + (number % (k * 10))*(number%b - number % (b / 10))) % a;
			//(部分积 + 截取被乘数的后N位*截取乘数的第M位),%a再截取部分积
			k /= 10;//k为截取被乘数时的系数
			b *= 10;
		}

		if (number == mul)
			cout << ' ' << mul;
	}

	cout << endl;
	system("pause");
	return 0;
}
 9.回文数

   打印所有不超过n(取n<256)的其平方具有对称性质的数(也称回文数)

对于要判定的数n计算出其平方后(存于tmp),按照“回文数”的定义要将最高位与最低位、次高位与次低位……进行比较,若彼此相等则为回文数。此算法需要知道平方数的位数,再一一将每一位分解、比较,此方法对于位数已知且位数不是太多的数来说比较适用
另一算法将平方后的(a的)每一位进行分解,按从低位到高位的顺序依次暂存到数组中,再将数组中的元素按照下标从大到小的顺序重新将其组合成一个数众(如n=15,则a=225且k=522),若k等于n×n则可判定n为回文数

int main()
{
	vector<int> en(16);
	int count = 0;	
	long unsigned old_mul = 0;
	long unsigned new_mul = 0;

	cout << "No.     number     it's square(palindrome)" << endl;

	for (int i = 1; i < 256; ++i)
	{
		int val = 1;//位权值
		old_mul = i * i;
		new_mul = 0;

		int pos = 0;
		for (pos = 0; old_mul != 0; ++pos)//从低到高分解old_mul的每一位到数组中
		{
			en[pos] = old_mul % 10;
			old_mul /= 10;
		}

		for (; pos > 0; --pos)
		{
			new_mul += en[pos - 1] * val;
			val *= 10;
		}

		if(new_mul == i * i)
			printf("%2d%10d%10d\n", ++count, i, new_mul);
	}

	cout << endl;
	system("pause");
	return 0;
}
 10.勾股数

   求100以内的所有勾股数

所谓勾股数,是指能够构成直角三角形三条边的三个正整数(a,b,c)
根据“勾股数”定义,所求三角形三边应满足条件 a2 + b2 = c2。可以在所求范围内利用穷举法找出满足条件的数
穷举时可采用三层循环对a,b,c的值进行查找,a: 1~100, b: a+1~100,c: b+1~100,再进一步考虑根据 a2 + b2 = c2 这个条件,在a、b值确定的情况下,没必要再利用循环一个一个去寻找c值。若a、b、c是一组勾股数,则 a2 + b2 的平方根一定等于c,c的平方应该等于a、b的平方和,所以可将a2+b2的平方根赋给c,再判断c的平方是否等于a2+b2,定义将变量定义为整型,a2 + b2 的平方根不一定为整数, 但变量c的类型为整型,将一个实数赋给一个整型变量时,可将实数强制转换为整型(舍弃小数点之后的部分)然后再赋值,这种情况下得到的c的平方与原来的的值肯定不相等,所以可利用这一条件进行判断

int main()
{
	cout << "  a     b    c       a     b    c       a     b    c       a     b    c" << endl;

	int count = 0;

	for (int a = 1; a <= 100; ++a)
	{
		for (int b = a + 1; b <= 100; ++b)
		{
			int c = (int)sqrt(a*a + b * b);
			if (c*c == a * a + b * b && a + b > c && a + c > b&& b + c > a && c <= 100)
			{
				printf("%4d %4d %4d     ", a, b, c);
				count++;
				if (count % 4 == 0)
				{
					cout << endl;
				}
			}
		}
	}

	system("pause");
	return 0;
}

你可能感兴趣的:(C/C++,C语言经典编程实例(六))