B. Neko Performs Cat Furrier Transform---异或的性质运用--Codeforces Round #554 (Div. 2)

博客围绕Neko Cat Furrier Transform题目展开,题目要求对给定数n进行t次操作使其值为2x - 1,操作包含异或和加1。介绍异或特性,即相同为0、不同为1,2x - 1二进制是多个1。解题思路是从高位找n二进制位,为0则异或2i + 1 - 1,还给出AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Neko Performs Cat Furrier Transform

time limit per test 1 second
memory limit per test 256 megabytes

题目链接http://codeforces.com/problemset/problem/1152/B

在这里插入图片描述
在这里插入图片描述


emmm,题目大意:给你一个数n,让你对他进行t次操作使得它的值为2x-1,你第一次只能将它异或2x-1,第二次只能对它+1,第三次…让你求t,并输出每个x;

题目有点想法,如果对异或不太熟悉的人可能有点迷,但实际上我们可以通过第一个样例来看:

首先我们将它(39)化为二进制:100111
异或会使得相同的变为0,不相同的变为1,而2x-1化为二进制则是1111111…(x-1个)。也就是说我们异或的时候会使得x-1位及以下的反转。

那么题目的意思就是让你在二进制的数据下降n的每位变成1。

那么也就好做了,我们对n从高位一位位地找下去,如果该位置为1,则继续找,否则我们就将它异或2i+1-1(i为二进制下的第i位)。至于第二个操作就不用管了,他是固定的操作。

当然我是先将它异或了一个2p-1(p为n的二进制下的长度)。这个完全可以删掉。。

以下是AC代码:

#include <bits/stdc++.h>
using namespace std;
int ok(int x)
{
	while (x){
		if (x%2==0) return 0; 
		x>>=1;
	}
	return 1;
}
int a[60],b[60];
int pow(int x,int y)
{
	int ans=1;
	for (int i=1; i<=y; i++)
	 ans*=x;
	return ans;
}
int main()
{
	int n;
	scanf ("%d",&n);
	if (ok(n)){
		printf ("0\n");
		return 0;
	}
	else {
		int ans=0,nb=0;
		while (!ok(n)){
			ans++;
			int cp=n,op=0;
			if (ans&1) {
				if (ans==1){
					while (cp) cp>>=1,op++;
					n^=pow(2,op)-1;
					a[++nb]=op;
				}
				else {
					int sb;
					memset(b,0,sizeof(b));
					while (cp) b[op++]=cp%2,cp>>=1;
					while (!b[op]) op--;
					for (int i=op; i>=0; i--) 
					 if (!b[i]){
					 	sb=i+1;
					 	break;
					 }
					n^=pow(2,sb)-1;
					a[++nb]=sb;
				}
			}
			else n++;
		}
		printf ("%d\n",ans);
		if (ans&1) 
		 for (int i=1; i<=ans/2+1; i++) printf ("%d ",a[i]);
		else 
		 for (int i=1; i<=ans/2; i++) printf ("%d ",a[i]);
		printf ("\n");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值