问题描述
有一天YMW看见竞赛室里面放着n个正面向上的杯子,他随手把所有的杯子翻转成正面向下的杯子了。后来突然想起来自己有两只手,于是他尝试同时翻转两只杯子,看下最后能不能翻转成为全部正面朝下。聪明的你看到了这一切,突然脑子里面闪过一个问题,假如每次同时翻转m只杯子,最后能全部翻转成为正面朝下吗?(初始时全部正面朝上)
输入
多组数据,每组数据两个数n和m,以-1,-1结尾
输出
对于每组数据,如果可以输出Yes,不能输出No
样例输入
6 2
5 3
-1 -1
样例输出
Yes
Yes
算法讨论
典型的翻转问题,广搜不会炸。然而我记得有O(1)的算法→_→
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 10005
int st[maxn];
bool f[maxn];
int n,m,t;
bool flag;
int bfs()
{
int hd=0,tl=1;
st[1]=n; f[n]=1;
while (hd!=tl)
{
hd++;
for (int i=0;i<=m;i++)
if (st[hd]>=i && n-st[hd]>=m-i)
{
tl++;
st[tl]=st[hd]-i+m-i;
if (f[st[tl]])
tl--;
else
f[st[tl]]=1;
if (st[tl]==0)
{
flag=1;
return 0;
}
}
}
return 0;
}
int main()
{
scanf("%d%d",&n,&m);
while (n!=-1 && m!=-1)
{
memset(f,0,sizeof(f));
memset(st,0,sizeof(st));
flag=0;
bfs();
if (flag)
printf("Yes\n");
else
printf("No\n");
scanf("%d%d",&n,&m);
}
return 0;
}
Pixiv ID:42109212