第一次双周赛

 

 7-2  a*b

 

#include<iostream>
using namespace std;
const int N=1200;
string s;
int num1[N],num2[N],ans[2*N];
char print[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
int read(int a[]){
	cin>>s;
	int n=s.length();
	for(int i=0;i<n;i++){
		if(s[n-1-i]>='0'&&s[n-1-i]<='9'){
			a[i]=s[n-i-1]-'0';	
		}
		else{
			a[i]=s[n-i-1]-'A'+10;
		}
	}
	return n;
}
int main(){
	int len1=read(num1);
	int len2=read(num2);
	int len3=2*N-1;
	for(int i=0;i<len1;i++){
		for(int j=0;j<len2;j++){
			ans[i+j]+=num1[i]*num2[j];
		}
	}
	for(int i=0;i<=len3;i++){
		if(ans[i]>=16){
			ans[i+1]+=ans[i]/16;
			ans[i]%=16;
		}
	}
	while(ans[len3]==0&&len3>0)len3--;
	for(int i=len3;i>=0;i--){
		cout<<print[ans[i]];
	}
	return 0;
}

十六进制的高精乘,不要把它转成十进制计算,直接在计算中转化一下,逢16进1,然后把10以后的转化为字母就行,但中间有一些细节还是要注意的。

7-3 山头狙击战

#include<iostream>
#include<algorithm>
using namespace std;
int n,m,a[100005];
bool check(int x){
    int step = 0;
    if(a[1] > m){
        step += a[1] - m;
    }
    for(int i = 2;i <= n; i++){
        step += x;
        if(a[i] - step < 0) return false;
        if(a[i] - step > m) step = a[i] - m;
    }
    return true;
}
int main()
{
    cin >> n >> m;
    for(int i = 1;i <= n;i++){
        cin >> a[i];
    }
    sort(a + 1, a + 1 + n);
    int l = -1,r = 1e9;
    while(l + 1 != r){
        int mid = (l + r) >> 1;
        if(!check(mid)) r = mid;
        else l = mid;
    }
    cout << l << endl;
    return 0;
}

二分答案和模板一样,主要题意理解,在二分前排序,调用的函数学大佬的思路写的,先大于最近的敌人,然后通过循环一个个比较。

7-4 Reversing Linked List

翻译一下:

给定一个常数K和一个单链表L,你应该反向L上的每K个元素的链接。例如,给定L为1→2→3→4→5→6,如果K=3,那么你必须输出3→2→1→6→5→4;如果K=4,则必须输出4→3→2→1→5→6。

输入规格:

每个输入文件包含一个测试用例。对于每种情况,第一行包含第一个节点的地址,一个正N(≤10的5次方),这是节点的总数,和一个正的K(≤N),这是要反转的子列表的长度。节点地址为5位非负整数,NULL用-1表示。

接下来是N行,每一行描述一个节点,格式如下:  Address Data Next

其中Address是节点的位置,Data是一个整数,Next是下一个节点的位置

思路:

用数组模拟(但还没学太会)

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 10005;
int temp;
int nt[N],dt[N],lt[N],ans[N];
int main() {
    int first, k, n, sum = 0;
    cin >> first >> n >> k;
    for (int i = 0; i < n; i++) {
        cin >> temp;
        cin >> dt[temp] >> nt[temp];
    }
    while (first != -1) {
        lt[sum++] = first;
        first = nt[first];
    }
    for (int i = 0; i < sum; i++) ans[i] = lt[i];
    for (int i = 0; i < (sum - sum % k); i++)
        ans[i] = lt[i / k * k + k - 1 - i % k];
    for (int i = 0; i < sum - 1; i++)
        printf("%05d %d %05d\n", ans[i], dt[ans[i]], ans[i + 1]);
    printf("%05d %d -1", ans[sum - 1], dt[ans[sum - 1]]);
    return 0;
}

7-5 一元三次方程

 

#include<bits/stdc++.h>
using namespace std;
#define lim 1e-6
double a,b,c,d,p,q,T,x1,x2,middle;
double f(double x) {
return a*x*x*x+b*x*x+c*x+d;//简便写法,避免重复写公式 
}
double func(double x,double y){
	double L=x,R=y;
	while(fabs(f(L)-f(R))>=lim)
	{
		middle=(R+L)/2.0;
		if(f(middle)*f(L)<0) R=middle;//零点存在定理 
		else L=middle;
	}
	return R;
}
int main(){
	cin>>T;
	while(T--)//T组数据 
	{
		cin>>a>>b>>c>>d>>p>>q;
		x1=(-2.0*b-sqrt(4*b*b-12*a*c))/(6*a);//求导找两个极值点,划分三个区间 
		x2=(-2.0*b+sqrt(4*b*b-12*a*c))/(6*a);
		if(x1>x2) swap(x1,x2);//确保区间顺序 
		cout<<fixed<<setprecision(6)<<func(p,x1)<<" "<<func(x1,x2)<<" "<<func(x2,q)<<endl;		
	}
	return 0;
}

 一元三次方程找零点:题目中给了零点存在定理,先求导找到一元二次方程的零点,再在这两个零点和两边界分出的三个区间上进行二分查找,其中在调用函数时调用了一个求函数值的函数,运用公式+理解题意~定义double类型进行二分找到精确度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值