BDF新春公开赛复习

2021年真题

1.位运算算式

输入格式

输入两个正整数 ab ,以及一个运算符(运算符只可能是与( & )、或( | )、异或( ^)。

输出格式

前两行依次输出a和b的32位二进制表示。

第三行输出32个 -(ASCLL码45)

第四行输出运算结果的32位二进制表示。

样例输入

5 6 |

样例输出

00000000000000000000000000000101
00000000000000000000000000000110
--------------------------------
00000000000000000000000000000011
#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>//scanf()
using namespace std;
void tenToTwo(int x){//十进制转二进制
	string s;
	for(int i=0;i<32;i++){
		s+=char('0'+x%2);
		x/=2;
	}
	reverse(s.begin(),s.end());//倒序
	cout<<s<<endl;//注意换行
}
int main(){
	//freopen("位运算算式.in","r",stdin); 在线下考试中,需要输入输出,可以在运行后再加
	//freopen("位运算算式.out","w",stdout);
	int a,b,ans;//a,b为输入的整数,ans是最后的答案
	char c;//运算符(&,|,^)
	cin>>a>>b>>c;
	switch(c){
		case '&': ans=a&b;break;
		case '|': ans=a|b;break;
		case '^': ans=a^b;break;
	}
	tenToTwo(a);//将a转化为二进制
	tenToTwo(b);//将b转化为二进制
	for(int i=1;i<=32;i++){//输出32个-
		cout<<"-";
	}
	cout<<endl;
	tenToTwo(ans);//将答案转化为二进制
	return 0;
}

重点摘录

void tenToB(int B,int x){//十进制转B进制
    char B_num[B];
    if(B<10){
        for(int i=0;i<B;i++)
            B_num[i]=i+48;
    }
    else{
        for(int i=0;i<B;i++)
            B_num[i]=i+48;
        for(int j=10;j<B;j++)
            B_num[j]='A'+j-10;
    }//定义好大于10的各个位置表示符号
    string result="";
    int n,m;
    while(x>=B){
        n=x/B;
        m=x%B;
        result+=B_num[m];
        x=n;
    }
    result+=B_num[n];
    for(int i=result.length()-1;i>=0;i--)
        cout<<result[i];
}
unsigned int BToTen(char *s, int length, int n)//n为B进制
{
    unsigned int res=0;
    char a[100]={0};
    for(int i=0;i<length;i++){
        a[i]=s[i];
        if(a[i]>='a'&&a[i]<='z')
        {
            a[i]-=32;
        }
        if(a[i]>='0'&&a[i]<='9')
        {
            a[i]-='0';
        }
        else if(a[i]>='A'&&a[i]<='A'+n-10)
        {
            a[i] = a[i] - 'A' + 10;
        }
        res=res*n+a[i];
    }
    return res;
}

最佳子段和

题目描述

给定长度为n的序列a[1...n]和q个询问,每次询问给一个整数k,请你找出一个非空连续子段a[l,r] ,使其子段和a[l]+...+a[r]最接近k。

形式上:找出最佳子段和sum(l,r)=a[l]+...+a[r],令abs(sum(l,r)-k)最小,输出这个最小值。

输入格式

第1行2个整数n,q,代表有q组询问。

第2行n个整数a[i]。

第3行q个整数代表每组询问的k。

输出格式

输出q行, 每行1个整数代表1组询问的答案。

样例输入

5 5
10 23 1 15 16
5 10 11 12 20

样例输出

4
0
1
2
3
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdio>//scanf()
using namespace std;
typedef long long LL;
LL a[100001],s[100001];
int main(){
	//freopen("最佳子段和.in","r",stdin);
	//freopen("最佳子段和.out","w",stdout);
	int n,q,k;
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		s[i]=s[i-1]+a[i];
	}
	for(int i=1;i<=q;i++){
		cin>>k;
		LL ans=1e18;
		int l=1;
		for(int r=1;r<=n;r++){
			while(l+1<=r&&(s[r]-s[l-1])>k){
				ans=min(ans,abs(s[r]-s[l-1]-k));
				l++;
			}
			ans=min(ans,abs(s[r]-s[l-1]-k));
			if(l+1<=r) ans=min(ans,abs(s[r]-s[l-1]-k));
		}
		cout<<ans<<endl;
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值