【問題解決方法】Luogu P2114 [NOI2014]起床困難症候群

移動:自分のブログ

トピック

Luogu P2114 [NOI2014]起床困難症候群

回答

質問の意味は次のように簡略化されます。0からmまでの数を見つけ、一連の操作の後にこの数が最大になるようにします。

元の数にはサイズの制限があり、取得する数はできるだけ大きくする必要があるため、制限を最大限に活用するには、最初から最後まで少しずつ貪欲になり、元の数が0か1かを判別する必要があります。得られる数を1にできる場合は、最善を尽くして選択すると同時に、元の数の制限を考慮して、元の数をできるだけ小さくします。

各ビットが0または1の場合の操作後の状態を記録する必要があります。すべてがゼロの数値とすべてが1の数値を使用して全体として動作するだけで、最後のビットが取り出されます。

コード

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,a0,a1,t,ans,st;
char ch[5];
inline void get_ans()
{
	for(int i=30;i>=1;i--)	//st是原数 
	{
		int cur=1<<(i-1);	//cur只有第i位为1 
		if(a0&cur) ans+=cur;	//优先考虑原数为0 
		else if(a1&cur&&st+cur<=m)	ans+=cur,st+=cur;
	}	//若得到的数必为0,则原数默认为0 
}
int main()
{
	scanf("%d%d",&n,&m);
	a0=0; a1=(1<<30)-1;
	for(int i=1;i<=n;i++)
	{
		scanf("%s%d",ch,&t);
		if(ch[0]=='A') a0&=t,a1&=t;
		else if(ch[0]=='O') a0|=t,a1|=t;
		else a0^=t,a1^=t;
	}
	get_ans();
	printf("%d\n",ans);

	return 0;
}

おすすめ

転載: blog.csdn.net/zjgmartin/article/details/108415768