C++ 计算概论A作业(第一阶段练习)

  1. 牛顿迭代求根
    在这里插入图片描述
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
/*x(n+1)=x(n)-f(x(n))/f'(x(n))
称为r的n+1次近似值
上式称为牛顿迭代公式*/
double newtoon(double n)
{
	int i = 1;
	if (n == 0)return 0;
	double x = 1.0;
	while (fabs(x-sqrt(n))>1e-6)
	{
		x = (x + n / x) / 2;
		i++;
	}
	cout << i << " ";
	return x;
};
int main()
{
	double n;
	while (cin >> n)
	{
		double root = newtoon(n);
		cout << setprecision(2)<< setiosflags(ios::fixed)<< root<< endl;
	}
	
}
  1. 判断四边形
    在这里插入图片描述

划重点:利用向量叉积判断另外两点是否在同侧,并且不在线上

#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
/*三点在一条直线上*/
struct quadrangle
{
	long long x, y;
}a, b, c, d;
int main()
{
	int count = 0;
	while (cin >> a.x >> a.y
		>> b.x >> b.y
		>> c.x >> c.y
		>> d.x >> d.y)
	{
		count++;
		quadrangle ab, bc, cd, da;//四条边转换为向量
		ab.x = b.x - a.x; ab.y = b.y - a.y;
		bc.x = c.x - b.x; bc.y = c.y - b.y;
		cd.x = d.x - c.x; cd.y = d.y - c.y;
		da.x = a.x - d.x; da.y = a.y - d.y;
		long long abc, bcd, cda, dab;
		abc = (long long)((ab.x * (c.y - a.y) - ab.y * (c.x - a.x)) * (ab.x * (d.y - a.y) - ab.y * (d.x - a.x)));
		bcd = (long long)((bc.x * (d.y - b.y) - bc.y * (d.x - b.x)) * (bc.x * (a.y - b.y) - bc.y * (a.x - b.x)));
		cda = (long long)((cd.x * (a.y - c.y) - cd.y * (a.x - c.x)) * (cd.x * (b.y - c.y) - cd.y * (b.x - c.x)));
		dab = (long long)((da.x * (b.y - d.y) - da.y * (b.x - d.x)) * (da.x * (c.y - d.y) - da.y * (c.x - d.x)));
		if (abc >0 && bcd >0 && cda >0 && dab > 0)
			cout << "yes" << endl;
		else cout << "no" << endl;

	}
}
  1. 数字7游戏
    在这里插入图片描述

划重点:注意单循环链表的终止条件 / 出圈条件的写法

#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
struct node
{
	node* next;
	int number;
};
int main()
{
	node* head;
	head = NULL;
	int n;
	cin >> n;
	node* s, * p;
	s = new node;
	p = head;
	for (int i = 1; i < n+1; i++)//建立环形链表
	{
		s->number = i;
		if (head == NULL)
			head = s;
		else p->next = s;
		p = s;
		if (i < n)
			s = new node;
		else s->next = head;
	}
	node* q;
	q = head;
	for (int i = 1; i <= 700; i++)
	{
		if (q == q->next)//环中只剩一个节点,不能写为q==MULL,会产生异常,内存无法访问
		{

			cout << q->number;
			break;
		}
		if (i % 7 == 0 || (i % 100) / 10 == 7 || (i % 10) == 7)//出圈
			{
				cout << q->number << endl;
				s->next = q->next;
				delete q;
				q = s->next;
			}
		else//不出圈
		{
			s = q;
			q = q->next;
		}
	}
}
  1. 等价类划分
    在这里插入图片描述

划重点:注意题目条件,数组该开足够大

#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main()
{
	int m, n, k;
	char ch;
	cin >> m >> ch >> n >> ch >> k;
	static int count[999] = { 0 };
	int equi[99][999] = {0};
	int j;//位数判断
	int max=0;
	for (int i = m; i < n; i++)
	{
		stringstream tmp,tmp1[5];
		string str;
		//string str = std::to_string(i);//将int类型转换为字符串
		//判断这是位数
		if (i / 10000 > 0)
			j = 5;
		else if (i / 1000 > 0)
			j = 4;
		else if (i / 100 > 0)
			j = 3;
		else if (i / 10 > 0)
			j = 2;
		else j = 1;
		tmp << i;//数字转换为流
		tmp >> str;//流转换为字符串
		int num[5] = {0}, sum = 0;
		for (int l = 0; l < j; l++)
		{
			tmp1[l] << str[l];
			tmp1[l] >> num[l];
			sum += num[l];
		}
		if (sum % k == 0)
		{
			equi[sum / k][count[sum / k]++] = i;
			if((sum / k)>max)
				max = sum / k;
		}
	}
	int temp;
	for (int i = 1; i < max+1; i++)
	{
		//排序
		for (int x = 0; x < count[i]-1; x++)
			for (int y = 0; y < count[i] -i-1; y++)
			{
				if (equi[i][y] > equi[i][y + 1])
				{
					temp = equi[i][y];
					equi[i][y] = equi[i][y + 1];
					equi[i][y + 1] = temp;
				}
			}
		//输出排序完成的等价类
		cout << equi[i][0];
		for (int j = 1; j < count[i]; j++)
			cout << ","<< equi[i][j] ;
		cout << endl;
	}
}
  1. 进制转换
    在这里插入图片描述

划重点:注意输入的可能是数字也可能是字母,定义为string类型
#include< sstream> 利用流来实现字符串和整数的转换

#include<iostream>
#include<string>
#include<sstream>
#include<cmath>
using namespace std;
int main()
{
	int s1, s2, s3;//进制
	string n1, n2;//两个数,可能出现字母所以定义为string
	cin >> s1 >> n1 >> s2 >> n2 >> s3;
	int n1_D=0, n2_D=0;//转换为十进制
	int n1_len = n1.size();//获得n1,n2的长度
	int n2_len = n2.size();
	int j1, j2; j1 = n1_len; j2 = n2_len;//由于不能修改len,j用来计数
	for (int i = 0; i < n1_len; i++)
	{
		stringstream tmp;
		int n1_temp=0;
		if (n1[i] >= '0' && n1[i] <= '9')
		{
			tmp << n1[i];
			tmp >> n1_temp;
		}
		else if (n1[i] >= 'a' && n1[i] <= 'f')
		{
			tmp << (n1[i] - 87);
			tmp >> n1_temp;
		}
		n1_D += n1_temp * pow(s1, float(--j1));
	}
	for (int i = 0; i < n2_len; i++)
	{
		stringstream tmp;
		int n2_temp=0;
		if (n2[i] >= '0' && n2[i] <= '9')
		{
			tmp << n2[i];
			tmp >> n2_temp;
		}
		else if (n2[i] >= 'a' && n2[i] <= 'f')
		{
			tmp << (n2[i] - 87);
			tmp >> n2_temp;
		}
		n2_D += n2_temp * pow(s2, float(--j2));
	}
	int sum;//求和
	sum = n1_D + n2_D;
	int c, m = 0, s[100];//和转化为s3进制
	while (sum != 0)
	{
		c = sum % s3;
		sum = sum / s3;
		m++; s[m] = c;
	}
	for (int k = m; k >= 1; k--)
	{
		if (s[k] >= 10)
			cout << (char)(s[k] + 87);//用a,b,c,d,e表示
		else
			cout << s[k];
	}
}  
	

还有几个写代码时遇到的问题,#define和const定义常量的区别

6.切蛋糕问题 大概意思就是一个蛋糕上有三块草莓,切成一样的三块,每块上必须有草莓,可以转换为两个点关于原点的张角问题。

#include<iostream>
#include<cmath>
using namespace std;
/*只要有 两个点的关于原点的张角 大于等于120度*/
int main()
{
	int t;
	cin>>t;
	int r,x[3],y[3];
	double distance[3];//与原点的距离的平方
	double angle[3];//与原点夹角的cos值
	for(int i=0;i<t;i++)
	{
		bool check;//指示是否存在>=120度的∠
		cin>>r;
		for(int j=0;j<3;j++)
		{
			cin>>x[j]>>y[j];
			distance[j]=pow(x[j],2.0)+pow(y[j],2.0);
		}
		angle[0]=(distance[1]+distance[2]-(pow((x[2]-x[1]),2.0)+pow((y[2]-y[1]),2.0)))/(2*sqrt(distance[1])*sqrt(distance[2]));
		angle[1]=(distance[0]+distance[2]-(pow((x[0]-x[2]),2.0)+pow((y[0]-y[2]),2.0)))/(2*sqrt(distance[0])*sqrt(distance[2]));
		angle[2]=(distance[0]+distance[1]-(pow((x[0]-x[1]),2.0)+pow((y[0]-y[1]),2.0)))/(2*sqrt(distance[0])*sqrt(distance[1]));
		/*计算两个点的关于原点的张角*/
		for(int i=0;i<3;i++)
		{
			if(distance[i]>pow(r,2.0)||distance[i]==0)//判断草莓是否在圆内,并且不在圆心处
				check=false;
			else 
			{
				if(angle[i]<=-0.5)
				{check=true;break;}
				else check=false;
			}
		}
		if(check==true)
			cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
}

7.二进制加法
最bt没有之一 本来转换成十进制long long来算,没想到后台测试数据大到逆天,只能采用二进制加法
不过我认为 只要后台数据没那么bt 转换也是可以用的

这是转换成十进制求和之后再转换成二进制的方法,一旦出现长达七八十的二进制数就无法得出正确结果辽。。。。

#include<iostream>
#include<string>
#include<sstream>
#include<cmath>
using namespace std;
int main()
{
	int n;
	cin >> n;
	string a, b;
	while (n--)
	{
		cin >> a >> b;
		int a_len, b_len, a_j, b_j;
		a_j = a_len = a.size();
		b_j = b_len = b.size();
		long long asum = 0, bsum = 0;
		long long sum = 0;
		for (int i = 0; i < a_len; i++)
		{
			int a_tmp;
			/*stringstream tmpa;
			tmpa << a[i];
			tmpa >> a_tmp;*/a_tmp = a[i] - '0';
			asum += (long long)(a_tmp * pow(2, float(--a_j)));
		}
		for (int i = 0; i < b_len; i++)
		{
			int b_tmp;
			/*stringstream tmpb;
			tmpb << b[i];
			tmpb >> b_tmp;*/b_tmp = b[i] - '0';
			bsum += (long long)(b_tmp * pow(2, float(--b_j)));
		}
		sum = asum + bsum;
		int c, m = 0, s[999];
		while (sum != 0)
		{
			c = sum % 2;
			sum = sum / 2;
			m++; s[m] = c;
		}
 		for (int k = m; k >= 1; k--)
			cout << s[k];
		cout << endl;
	}
}

所以还是采用正常方法。。

#include<iostream>
#include<string>
using namespace std;
void Add(char s1[], char s2[])
{
	int num1[1000] = { 0 }, num2[1000] = { 0 };
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	int  i = 0, j = 0;
	for (i = len1 - 1, j = 0; i >= 0; i--)//将字符串转换成1/0存入数组
		num1[j++] = s1[i] - '0';
	for (i = len2 - 1, j = 0; i >= 0; i--)
		num2[j++] = s2[i] - '0';
	for (i = 0; i < 1000; i++)//二进制之间的加法
	{
		num1[i] += num2[i];
		if (num1[i] >= 2)
		{
			num1[i] -= 2;
			num1[i + 1]++;
		}
	}
	//在倒叙输出num1[i]时去掉此数组后边多余的0;   
	int del = 1000 - 1;

	while (num1[del] == 0)
		del--;
	for (int k = del; k >= 0; k--)
		cout << num1[k];
	cout << endl;
}
int main()
{
	int n;
	cin >> n;
	char s1[1000], s2[1000];
	for (int i = 0; i < n; i++)
	{
		cin >> s1 >> s2;
		Add(s1, s2);
	}

}

8.在区间内写出所有素数对:两个素数之差还是素数 相差为2的

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
bool prime(long long x)//判断是否是素数
{
	bool flag = false;
	for (long long j = 2; j < sqrt(double(x)) + 1; j++)//判断是否为素数
	{
		if (x % j == 0 && j != x)
		{
			flag = false;
			break;
		}
		else
			flag = true;
	}
	return flag;
};
int main()
{
	long long m, n;
	char ch;
	cin >> m >> ch >> n;
	long long primeNum[100000] = {0};
	long long count = 0;
	for (long long i = m; i <= n; i++)
	{
		if (prime(i)==true)
		{
			primeNum[count++] = i;
		}
	}
	/*if(primeNum[count-1]==5|| count < 2)
		cout << "NULL" << endl;*/
	bool check = false;
	if (primeNum[0] == 2)
	{
		for (long long i = 1; i < count; i++)//第一个数
		{
			if (primeNum[i] - 2 != 1 && prime(primeNum[i] - 2) == true)
			{
				check = true;
				cout << "(" << primeNum[0] << "," << primeNum[i] << ")" << endl;
			}
		}
		for (long long i = 1; i < count - 1; i++)
		{
			if (primeNum[i + 1] - primeNum[i] == 2)
			{
				cout << "(" << primeNum[i] << "," << primeNum[i + 1] << ")" << endl;
				check = true;
			}
		}
	}
	else
	{
		for (long long i = 0; i < count - 1; i++)
		{
			if (primeNum[i + 1] - primeNum[i] == 2)
			{
				cout << "(" << primeNum[i] << "," << primeNum[i + 1] << ")" << endl;
				check = true;
			}
		}
	}
	if (check == false)
		cout << "NULL" << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值