新生赛(巧克力豆-关于异或的使用)

不打算把所有的新生赛题目都写成博客上的,感觉这道写了挺久,所以记一下,哈哈哈

首先,题目如下


Chocolate (10分)
C时间限制:1000 毫秒 | C内存限制:3000 Kb
题目内容
还是小W,他挑选完给小H的完美巧克力之后自己吃完了剩下的巧克力,他发现:
巧克力是世界上最好吃的东西!
所以他火速下单又购买了一批巧克力。
这次的巧克力中有黑白两种巧克力豆,小W仔细观察,认真分析,取出两种巧克力,摆成一排:你看这个巧克力豆又大又圆,多像二进制串啊!
所以他决定用黑白巧克力豆来出这道题。
现在抽象此问题,给定p,q,给出长度为p的二进制串,将此二进制串向后移动一次,共移动q-1次,可以算出p+q-1位的每一位异或值,所谓异或即是00=0,11=0,0^1=1,即相同取零, 相异取1,当p = 6, q = 3时
101010
  101010
    101010
11010110
即结果为11010110, 现已知结果, 求初始的二进制串
输入描述
第一行两个正整数
第二行(p + q - 1)位二进制串
数据范围:
0<m<=n<=1000000
1<=n+m-1<=1000000

输出描述
输出长为p的二进制串

输入样例
6 3
11010110

输出样例
101010


然后开始解题思路
因为此题需要用到异或,所以我们先来了解一下异或是什么(下图皆源自百度百科)
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

然后利用上图中第五条运算法则来推算一遍此题的规律
设数组a[1000000]中存的是结果数字串11010110
数组b[1000000]中存的是原数字串101010
然后我们来推算
101010
  101010
    101010
11010110
当i<q时
a[0]=b[0];         b[0]=a[0];
a[1]=b[1] ^ b[0];      b[1]=a[1]^a[0];
a[2]=b[0] ^ b[1] ^ b[2];   b[2]=a[2] ^ a[1];
所以在i<q时,b[i]=a[i]^a[i-1];
当q>=i>=p时
a[3]=b[1]^ b[2]^ b[3];   b[3]=a[3] ^ a[2] ^a[0] (a[0]=b[0]);
a[4]=b[2]^ b[3]^ b[4];    b[4]=a[4]^ a[3]^ a[0]^a[1] (a[0] ^a[1]=b[1]);
a[5]=b[3] ^b[4] ^b[5];   b[5]=a[5] ^a[4] ^a[2] ^a[1] (a[2] ^ a[1]=b[2]);
a[6]=b[4]^ b[5] ^b[6];  b[6]=a[6] ^a[5] ^a[3] ^a[2] ^a[0] (a[3] ^ a[2] ^a[0]=b[3])
所以在q>=i>=p时,b[i]=a[i]^ a[i-1]^ b[i-q];
最终代码如下

#include<stdio.h>  
char a[1000005];
int p,q,b[1000005];
int main()
{  
	int j=0,i;
	scanf("%d%d",&p,&q);
	scanf(" ");		//刷新缓冲区;
	gets(a);
	b[j]=(a[0]=='1');//因为第一个数都是与0异或,任何数与0异或都为它本身
	for(int i=1;i<p;i++)
	{
		j++;
		if(i<q)
		{
			b[j]=(a[i]-'0')^(a[i-1]-'0');
		}
		else
		{
			b[j]=(a[i]-'0')^(a[i-1]-'0')^b[i-q];
		}
	}
	for(int i=0;i<j+1;i++)
        	printf("%d",b[i]);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值