poj2426 Remainder

题意:

  • 多组数据。
  • 给n,m,k三个数(-1000<=n<=1000,1<k<=1000,0<m<=1000)
  • 有四种操作n+m,n-m,n*m,n%m
  • 求最少经过多少步将n变为(n+1)%k

思路:

求最小步数,审题后发现用BFS。枚举4种操作,特别注意n%m的操作,因为n可能为负数,所以%操作要用(n%m+m)%m。因为是多组数据,所以每次都要清空队列与flag数组(千万注意,贡献了一次Wa)。


代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
int n,m,k,ans;
string ans1;
bool flag[10000005];
 struct ss
{
	int num,sum;
	string r;
};

 void bfs()
{
	queue<ss>q;
	int sum=m*k,s;
	ss res,tmp;
	s=((n+1)%k+k)%k;
	flag[(n%sum+sum)%sum]=1;
	res.num=0; res.sum=n; res.r="";
	q.push(res);
	while (!q.empty())
	{
		res=q.front(); q.pop();
		if ((res.sum%k+k)%k==s)
		{
			ans=res.num; ans1=res.r;
			return;
		}
		for (int i=0; i<4; i++)
		{
			if (i==0) {tmp.sum=(res.sum+m)%sum; tmp.r=res.r+"+";}
			else if (i==1) {tmp.sum=(res.sum-m)%sum; tmp.r=res.r+"-";}
			else if (i==2) {tmp.sum=(res.sum*m)%sum; tmp.r=res.r+"*";}
			else {tmp.sum=(res.sum%m+m)%m%sum; tmp.r=res.r+"%";}
			tmp.sum=(tmp.sum+sum)%sum;
			if (!flag[tmp.sum])
			{
				flag[tmp.sum]=1;
				tmp.num=res.num+1; q.push(tmp); 
			}
		}
	}
}

 int main()
{
	while(scanf("%d%d%d",&n,&k,&m))
	{
		if (!n&&!m&&!k) break;
		ans=0;
		memset(flag,0,sizeof(flag));
		bfs();
		printf("%d\n",ans);
		if(ans)	cout<<ans1<<endl;
	}
	return 0;
}
posted @ 2019-08-25 19:43  Allen_Gun  阅读(112)  评论(0编辑  收藏  举报