码迷,mamicode.com
首页 > 其他好文 > 详细

zoj 3327 Friend Number 贪心

时间:2015-04-19 11:36:23      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:贪心   数论   

Friend Number

Time Limit: 1 Second      Memory Limit: 32768 KB

Given a positive integer x, let P(x) denotes the product of all x‘s digits. Two integers x and y are friend numbers if P(x) = P(y). Here comes the problem: Given a positive integer x, of course it has a lot of friend numbers, find the smallest one which is greater than x.

Input

There are multiple test cases. The first line of input is an integer T (0 < T < 230) indicating the number of test cases. Then T test cases follow. Each case is an integer x (0 < x <= 101000). You may assume that x has no leading zero.

Output

For each test case, output the result integer in a single line. You should not output a number with leading zero.

Sample Input

3
12
19
222

Sample Output

21
33
241

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3327

题意:找出比n大的 最小的数,要求每个位上的数字 乘积 与n每个位上的数字 乘积要相等。

参考了别人的题解

做法:如果有0 ,特殊处理。分为末尾只有一个0,不是这种情况。

1、如果只有个位一个0,就从十位上往高位找,找不是9的,找到加1,结束。找的过程遇到9,都改为0。如果都是9,就在数字最左边加一个1。

2、如果有0,且不是上诉情况,那就直接从个位往高位走,遇到9,变0,遇到非9 ,加1,结束。

3、如果没有0的话,把从个位开始,素数分解,并记录所有的素数。分解完一位,就判断下分解出来的素数能不能组成比 这一位大的 个位数,能的话取最小的这个数,设这个位为id。如123  ,个位分解完,得素数3,十位分解完得素数2,这个时候可以用分解的素数有2,3,2*3=6,要比2大且最小,所以选3。 所以十位改为3,素数3的个数减1。 接下来从个位,不停地放 已经得到的素数能组成最大的数,直到id的后一位为止。

如果一直没找到id位,就直接在原来的数前面加个‘1’ 输出即可。

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char str[1010];

int ji[10];
int prim[4]={2,3,5,7};
int ling(char str[])
{
	int flag=0;
	for(int i=0;str[i];i++)
	{ 
		if(str[i]=='0')
			flag++;
	}
	return flag;
}
void add(char ch)
{
	ch-='0';
	if(ch==4)
		ji[2]+=2;
	else if(ch==6)
	{
		ji[2]++;
		ji[3]++;
	}
	else if(ch==8)
		ji[2]+=3;
	else if(ch==9)
		ji[3]+=2;
	else
		ji[ch]++;
}

int ok(char ch)
{
	ch-='0';
	if(ch==1)
		return 1;
	if(ch==4)
	{
		if(ji[2]>=2)
			return 1;
		return 0;
	}
	else if(ch==6)
	{
		if(ji[2]>=1&&ji[3]>=1)
			return 1;
		return 0;
	}
	else if(ch==8)
	{
		if(ji[2]>=3)
			return 1;
		return 0;
	}
	else if(ch==9)
	{
		if(ji[3]>=2)
			return 1;
		return 0;
	}
	else
	{
		if(ji[ch])
			return 1;
		return 0;
	}
	return 1;
}

void dec(char ch)
{
	ch-='0';
	for(int i=0;i<=3;i++)
	{
		while(prim[i]&&ch%prim[i]==0)
		{
			ji[prim[i]]--;
			ch/=prim[i];
		}
	}
}

void change(char str[],int len,int id)
{
	for(int i=len-1;i>id;i--)
	{
		for(char j='9';j>='1';j--)
		{
			if(ok(j))
			{
				dec(j);
				str[i]=j;
				break;
			}
		}
	}
}
void deal(char str[],int len)
{
	memset(ji,0,sizeof ji);
	int flag=0;
	for(int i=len-1;i>=0;i--)
	{
		add(str[i]);
		for(char j=str[i]+1;j<='9';j++)
		{
			if(ok(j))
			{
				dec(j);
				str[i]=j;
				change(str,len,i);
				flag=1;
				break;
			}
		}
		if(flag)
			break;
	}
	if(flag==0)
	{
		printf("1");
		change(str,len,-1);
	}
}

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		scanf("%s",str);
		int len=strlen(str);
		int cnt=ling(str);
		if(cnt==1&&str[len-1]=='0')//只有末尾一个零
		{
			int flag=0;
			for(int i=len-2;i>=0;i--)
			{
				if(str[i]!='9')
				{
					str[i]++;
					flag=1;
					break;
				}
				else 
					str[i]='0';
			} 
			if(flag==0)
				printf("1");
		}
		else if(cnt>=1) 
		{
			for(int i=len-1;i>=0;i--)
			{ 
				if(str[i]!='9')
				{
					str[i]++; 
					break;
				}
				else 
					str[i]='0';
			}
		}
		else
			deal(str,len);
		 
		printf("%s\n",str);

	}
	return 0;
}




zoj 3327 Friend Number 贪心

标签:贪心   数论   

原文地址:http://blog.csdn.net/u013532224/article/details/45127303

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!