NEUQ-ACM预备队训练-第一次双周赛

前言及题解思路

这次双周赛的作业考察了模拟与高精度,二分查找与二分答案和线性表的内容,总体来说难度适中,不算太难

  • 第一题使用了单向链表,将字符L存储到链表,然后标记链表节点两侧的字符‘ . ’,最后再将未标记的字符’ . '转化为字符‘ C ’,再将字符串输出即可

  • 第二题模拟十六进制乘法,建立两个数组存储两个十六进制数的每一位,再建立一个结果数组,按照类似列竖式的方法算出相乘之后的每一位,然后存储到新数组中,再完成进位之后即可输出,注意把超过9的数字转化为abcdef六种字符

  • 第三题使用了二分答案的方法,从1到最远敌人到达的时间进行二分,判断答案是否符合条件以找出最长装弹时间,判断函数check先找出开完第一枪解决第一个敌人的时间,然后循环剩下的敌人,判断他们到眼前所需的时间是否大于等于装弹时间,若小于则该装弹时间过长不符合要求

  • 第四题使用数组去模拟,同时通过本节点的地址沟通了本节点的a值和下一个节点

  • 第五题使用了二分法,先用求根公式求出来两个极值点,再把原图形分成三个区间,用二分法分别去求三个零点

(1)百合

题目

在这里插入图片描述

代码

#include<bits/stdc++.h>
using namespace std;
struct list_s {
	char x;
	int f;
	int next;
};
int main() {
	int n;
	cin>>n;
	char s[n];
	int ff=0;
	for(int i=0; i<n; i++) {
		cin>>s[i];
		if(s[i]=='L')	ff=1;
	}
	if(ff==0) {
		for(int i=0; i<n; i++) {
			cout<<'C';
		}
		return 0;
	}
	list_s x[n+1];
	int temp=n;
	for(int i=0; i<n; i++) {
		x[i].f=1;
		if(s[i]=='L') {
			x[temp].next=i;
			temp=i;
			x[temp].next=n;
		}
	}
	temp=x[n].next;
	while(temp!=n) {
		if(temp>0) {
			x[temp-1].f=0;
			x[temp+1].f=0;
		}
		if(temp==0) {
			x[temp+1].f=0;
		}
		temp=x[temp].next;
	}
	for(int i=0; i<n; i++) {
		if(x[i].f==0||s[i]=='L'	)	cout<<s[i];
		if(x[i].f==1&&s[i]=='.')	cout<<'C';
	}
	return 0;
}

(2)a*b

题目

在这里插入图片描述

代码

#include<bits/stdc++.h>
using namespace std;
void addd(int c[]) {
	for(int i=0; i<2003; i++) {
		if(c[i]>=16) {
			c[i+1]+=c[i]/16;
			c[i]%=16;
		}
	}
}
int main() {
	int a[1001];
	int b[1001];
	int c[2003];
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	string s;
	cin>>s;
	for(int i=s.length()-1; i>=0; i--) {
		if(s[i]>='0'&&s[i]<='9') {
			a[s.length()-1-i]=s[i]-'0';
		}
		if(s[i]=='A') {
			a[s.length()-1-i]=10;
		}
		if(s[i]=='B') {
			a[s.length()-1-i]=11;
		}
		if(s[i]=='C') {
			a[s.length()-1-i]=12;
		}
		if(s[i]=='D') {
			a[s.length()-1-i]=13;
		}
		if(s[i]=='E') {
			a[s.length()-1-i]=14;
		}
		if(s[i]=='F') {
			a[s.length()-1-i]=15;
		}
	}
	string s1;
	cin>>s1;
	for(int i=s1.length()-1; i>=0; i--) {
		if(s1[i]>='0'&&s1[i]<='9') {
			b[s1.length()-1-i]=s1[i]-'0';
		}
		if(s1[i]=='A') {
			b[s1.length()-1-i]=10;
		}
		if(s1[i]=='B') {
			b[s1.length()-1-i]=11;
		}
		if(s1[i]=='C') {
			b[s1.length()-1-i]=12;
		}
		if(s1[i]=='D') {
			b[s1.length()-1-i]=13;
		}
		if(s1[i]=='E') {
			b[s1.length()-1-i]=14;
		}
		if(s1[i]=='F') {
			b[s1.length()-1-i]=15;
		}
	}
	for(int i=0;i<1001;i++){
		for(int j=0;j<1001;j++){
			c[i+j]+=a[i]*b[j];
		}
	}
	addd(c);
	int f=0;
	for(int i=2002;i>=0;i--){
		if(c[i]!=0||f==1){
			if(c[i]>=0&&c[i]<=9)	cout<<c[i];
			if(c[i]==10)	cout<<'A';
			if(c[i]==11)	cout<<'B';
			if(c[i]==12)	cout<<'C';
			if(c[i]==13)	cout<<'D';
			if(c[i]==14)	cout<<'E';
			if(c[i]==15)	cout<<'F';
			f=1;
		}
	}
	return 0;
}

(3)山头狙击战

题目

在这里插入图片描述

代码

#include<bits/stdc++.h>
using namespace std;
int check(int a[],int mid,int m,int n,int max1){
	int sum=1;
	int now=max(0,a[0]-m)+mid;
	for(int i=1;i<=n-1&&now<=max1;i++){
		if(a[i]>=now){
			sum++;
			now+=mid;
		}
		else{
			break;
		}
	}
	return sum==n;
}
int main() {
	int n,m;
	cin>>n>>m;
	int a[n];
	int max1=0;
	for(int i=0;i<n;i++){
		cin>>a[i];
		if(a[i]>=max1)	max1=a[i];
	}
	sort(a,a+n);
	int L=1,R=max1,ans=0;
	while(R>=L){
		int mid=(L+R)/2;
		if(check(a,mid,m,n,max1)){
			ans=mid;
			L=mid+1;
		}
		else{
			R=mid-1;
		}
	}
	cout<<ans;
	return 0;
}

(4)反转链表

题目

在这里插入图片描述

代码

#include<bits/stdc++.h>
using namespace std;
int a[10005], b[10005];
int c[10005];
int first, n, k;
int main() {
	cin >> first >> n >> k;
	for (int i = 0; i < n; i++) {
		int add, anum, nextp;
		cin >> add >> anum >> nextp;
		a[add] = anum;
		b[add] = nextp;
	}
	int index = 0;
	for (int i = first; i != -1; i = b[i]) {
		c[index++] = i;
	}
	for (int i = 0; i + k <= index; i+=k) {
		reverse(c + i, c + i + k);
	}
	for (int i = 0; i < index; i++) {
		if (i >= index - 1)printf("%05d %d -1\n", c[i], a[c[i]]);
		else printf("%05d %d %05d\n", c[i], a[c[i]], c[i + 1]);
	}
	return 0;
}

(5)一元三次方程

题目

请添加图片描述
请添加图片描述

代码

#include<bits/stdc++.h>
using namespace std;
int check1(double a,double b,double c,double d,double mid) {
	if(a*mid*mid*mid+b*mid*mid+c*mid+d>=0) {
		return 1;
	} else	return 0;
}
int check2(double a,double b,double c,double d,double mid) {
	if(a*mid*mid*mid+b*mid*mid+c*mid+d<=0) {
		return 1;
	} else	return 0;
}
int main() {
	int T;
	cin>>T;
	for(int i=0; i<T; i++) {
		double a,b,c,d,p,q;
		cin>>a>>b>>c>>d>>p>>q;
		double L,R;
		double mid1,mid2,mid3;
		double x1,x2,x3;
		double s1=1.0*((-2)*b-sqrt(4.0*b*b-4.0*c*3*a))/(6.0*a);
		double s2=1.0*((-2)*b+sqrt(4.0*b*b-4.0*c*3*a))/(6.0*a);
		if(s1>s2)	swap(s1,s2);
		if(a>0) {
			L=p,R=s1;
			while(L<=R) {
				mid1=1.0*(L+R)/2.0;
				if(check1(a,b,c,d,mid1)==1) {
					x1=mid1;
					R=mid1-0.00000001;
				} else {
					L=mid1+0.00000001;
				}
			}
			L=s2,R=q;
			while(L<=R) {
				mid3=1.0*(L+R)/2.0;
				if(check2(a,b,c,d,mid3)) {
					x3=mid3;
					L=mid3+0.0000001;
				} else {
					R=mid3-0.00000001;
				}
			}
			L=s1,R=s2;
			while(L<=R) {
				mid2=1.0*(L+R)/2.0;
				if(check1(a,b,c,d,mid2)) {
					x2=mid2;
					L=mid2+0.0000001;
				} else {
					R=mid2-0.00000001;
				}
			}
		}
		if(a<0) {
			L=p,R=s1;
			while(L<=R) {
				mid1=1.0*(L+R)/2.0;
				if(check2(a,b,c,d,mid1)==1) {
					x1=mid1;
					R=mid1-0.00000001;
				} else {
					L=mid1+0.00000001;
				}
			}
			L=s2,R=q;
			while(L<=R) {
				mid3=1.0*(L+R)/2.0;
				if(check1(a,b,c,d,mid3)) {
					x3=mid3;
					L=mid3+0.0000001;
				} else {
					R=mid3-0.00000001;
				}
			}
			L=s1,R=s2;
			while(L<=R) {
				mid2=1.0*(L+R)/2.0;
				if(check2(a,b,c,d,mid2)) {
					x2=mid2;
					L=mid2+0.0000001;
				} else {
					R=mid2-0.00000001;
				}
			}
		}
		printf("%.6lf %.6lf %.6lf\n",x1,x2,x3);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值