poj2426 Remainder

题意:

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

思路:

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


代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int n,m,k,ans;
string ans1;
bool flag[10000005];
 struct ss
{
	int num,sum;
	string r;
};

 void bfs()
{
	queueq;
	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<

你可能感兴趣的:(poj2426 Remainder)