【日常刷题】NOIP练习题题解

1.小X与位运算

题目描述
自从上次小X 搞定了完美数之后,他最近在研究一项和计算机密切相关的黑科技。要知道在计算机的内部,数据都是以二进制的形式来进行存储的,而它使用的计算方法也和我们平时的加减乘除四则运算 有所不同,它使用的是位运算。那什么是位运算呢? 基础位运算有三种符号,分别是 and,or,xor(分别对应 pascal 中的 and,or,xor 三种运算符 号)。
以 and 为例,两个二进制数在做 and 运算时,分别对两个二进制数的每一位做 and 运算。而对每一 位做and 运算时,遵守以下规则:只有当两个数的这一位都是 1 时,运算结果才为 1,否则就是 0。例如 1101 和10101 做and 运算之后结果为101(高位不足用0 补齐,最后结果忽略前导0)。 通俗点讲 and 运算就是按位做乘法,即将两个二进制数从高位到低位依次对齐,然后每一位上对齐 的两个数相乘即得到这一位的结果 。我们可以列一个简单的例子来说明个and运算:01101 and 10101 = 00101。
而or,xor 的运算方法类似,唯一不同的是在对每一位做运算时遵循的方法不同。 or 运算遵守以下规则:只有当两个数的这一位都是 0 时,运算结果才为 0,否则就是 1。例如1101or10101=11101。
xor 运算遵守以下规则:只有当两个数的这一位相同时,运算结果才为0,否则就是1。例如1101xor10101=11000 。
小 X想知道两个很大很大的二进制数,在做完位运算之后, 最后的结果是什么。而小X 自己无法知道正确答案是什么,他只好求助于你来帮助他解决这个问题。
输入格式
输入数据第一行是一个字符串,由字符0 和1组成,表示一个二进制数。 第二行也是一个字符串,由字符0 和1组成,同样表示一个二进制数。 第三行还是一个字符串,一定是and,or,xor三个中一种,表示运算符号。 注意输入的二进制数没有前导零,字符个数可能会超过255 个。
输出格式
输出一行一个字符串,由字符0和1 组成,表示最后运算得到的二进制数。 注意输出的二进制数不能带有前导零,即输出的第一个字符不能为0。
样例数据
input
110100
11001
or
output
111101

题解:
读入两个字符串s1和s2,设长度分别是len1和len2,则:
1.len1=len2,直接进行运算
2.len1<len2,第0~len2-len1-1位是第二个字符串与0进行逻辑运算,接下来再逐渐配对。
3.len1>len2,与2相反。

CODE

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200000

string s;
char s1[MAXN];
char s2[MAXN];
int ans[MAXN],len1,len2,Max;

void work_xor()
{
   
    for (int i=0;i<Max;++i)
    {
   
        int det=abs(len1-len2);
    	if (len1!=Max && len2==Max)
    	{
   
    		if (i<len2-len1) ans[i]=0^int(s2[i]-48);
    		else ans[i]=int(s1[i-det]-48)^int(s2[i]-48);
    	}
    	if (len1==Max && len2!=Max)
    	{
   
    		if (i<len1-len2) ans[i]=0^int(s1[i]-48);
    		else ans[i]=int(s1[i]-48)^int(s2[i-det]-48);
    	}
    	if (len1==Max && len2==Max)
    	    ans[i]=int(s1[i]-48)^int(s2[i]-48);
    }
}

void work_or()
{
   
    for (int i=0;i<Max;++i)
    {
   
        int det=abs(len1-len2);
    	if (len1!=Max && len2==Max)
    	{
   
    		if (i<len2-len1) ans[i]=0|int(s2[i]-48);
    		else ans[i]=int(s1[i-det]-48)|int(s2[i]-48);
    	}
    	if (len1==Max && len2!=Max)
    	{
   
    		if (i<len1-len2) ans[i]=0|int(s1[i]-48);
    		else ans[i]=int(s1[i]-48)|int(s2[i-det]-48);
    	}
    	if (len1==Max && len2==Max)
    	    ans[i]=int(s1[i]-48)|int(s2[i]-48);
    }
}

void work_and()
{
   
    for (int i=0;i<Max;++i)
    {
   
        int det=abs(len1-len2);
    	if (len1!=Max && len2==Max)
    	{
   
    		if (i<len2-len1) ans[i]=0&int(s2[i]-48);
    		else ans[i]=int(s1[i-det]-48)&int(s2[i]-48);
    	}
    	if (len1==Max && len2!=Max)
    	{
   
    		if (i<len1-len2) ans[i]=0&int(s1[i]-48);
    		else ans[i]=int(s1[i]-48)&int(s2[i-det]-48);
    	}
    	if (len1==Max && len2==Max)
    	    ans[i]=int(s1[i]-48)&int(s2[i]-48);
    }
}

int main()
{
   
	freopen("bignum.in","r",stdin);
	freopen("bignum.out","w",stdout);
	cin>>s1;
	cin>>s2;
	cin>>s;
	len1=strlen
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值