hdu 1664 Different Digits, spoj 3929 , 同余,bfs


Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 820    Accepted Submission(s):
202

Problem Description

Given a positive integer n, your task is to find a positive integer m, which is a multiple of n, and that m contains the least number of different digits when represented in decimal. For example, number 1334 contains three different digits 1, 3 and 4.

Input

The input consists of no more than 50 test cases. Each test case has only one line, which contains a positive integer n ( 1<=n < 65536). There are no blank lines between cases. A line with a single `0‘ terminates the input.

Output

For each test case, you should output one line, which contains m. If there are several possible results, you should output the smallest one. Do not output blank lines between cases.

Sample Input

7
15
16
101
0

Sample Output

7
555
16
1111

题意:

给一个n,让你找出含不同数字最少的n的倍数,如果含不同数字相同,则输出最小的。

同余,bfs

定理:

对于任意的整数n,必然存在一个由不多于两个的数来组成的一个倍数。

因为a,aa,aaa……取n+1个,则必有两个模n余数相同,相减即得n的倍数m。而m只由a、0组成。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <set>
#include <queue>
#include <string>
using namespace std;

const int maxn = 100000;
int N;
int a[5], cnt;
string ans;
int ansn;
struct node{
	short d;
	int pre;
	int re;
};
node q[maxn];
int head, tail;

string tmp;

inline int cmpstr(string a, string b){
	if( a.size()<b.size() || (a.size()==b.size()&&a<b) )
		return -1;
	return 1;
}
bool hash[70000];
bool bfs(){
	head = tail = 0;
	node nt, qt;
	memset(hash, 0, sizeof hash );
	for(int i=0; i<cnt; ++i){
		if(a[i]==0) continue;
		nt.d = a[i];
		nt.pre = -1;
		nt.re = a[i] % N;
		q[tail++] = nt;
		hash[nt.re] = 1;
	}
	while(head<tail){
		nt = q[head];
		for(int i=0; i<cnt; ++i){
			qt.d = a[i]; qt.pre = head; qt.re = (nt.re*10+a[i]) % N;
			if(!hash[qt.re]){
				hash[qt.re] = 1;
				q[tail++] = qt;
			}
			if(qt.re==0){
				tmp = "";
				for(int pos=tail-1; pos!=-1; pos = q[pos].pre){
                    tmp += q[pos].d + '0';
				}
				reverse(tmp.begin(), tmp.end());
				return 1;
			}
		}
		head++;
	}
	return 0;
}

void solve(int N){
	set<int> st;
	ans = "";
	for(int x=N, y; x>0; x/=10){
		y = x % 10;
		ans += y + '0';
		st.insert(y);
	}
	ansn = st.size();
	reverse(ans.begin(), ans.end());
	cnt = 1;
	for(a[0]=1; a[0]<10; ++a[0]){
        if(bfs())
        if(ansn>cnt || (ansn==cnt&&cmpstr(tmp,ans)<0) ){
            ans = tmp;
            ansn = cnt;
        }
	}
	if(ansn==cnt){
        printf("%s\n", ans.c_str());
        return ;
	}
	cnt = 2;
	for(a[0]=0; a[0]<10; ++a[0]){
		for(a[1]=a[0]+1; a[1]<10; ++a[1]){
		   if(bfs())
           if(ansn>cnt ||(ansn==cnt&&cmpstr(tmp,ans)<0)){
                ans = tmp;
                ansn = cnt;
           }
		}
	}
	printf("%s\n", ans.c_str());
}

template<class T>
inline bool scan_d(T &ret){
    char c; ret = 0;
    while((c=getchar())<'0'||c>'9');
    while(c>='0'&&c<='9') ret = ret*10 + (c-'0'),c=getchar();
    return 0;
}
int main(){
   // freopen("in.txt","r",stdin);
	while(true){
        scan_d(N);
		if(N==0) break;
		if(N<10){
			printf("%d\n", N);
			continue;
		}
		solve(N);
	}
	return 0;
}
时间: 2024-12-20 12:28:43

hdu 1664 Different Digits, spoj 3929 , 同余,bfs的相关文章

hdu 1664 Different Digits

Different Digits Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1138    Accepted Submission(s): 296 Problem Description Given a positive integer n, your task is to find a positive integer m,

2014年百度之星程序设计大赛 - 初赛(第一轮) hdu Grids (卡特兰数 大数除法取余 扩展gcd)

题目链接 分析:打表以后就能发现时卡特兰数, 但是有除法取余. f[i] = f[i-1]*(4*i - 2)/(i+1); 看了一下网上的题解,照着题解写了下面的代码,不过还是不明白,为什么用扩展gcd, 不是用逆元吗.. 网上还有别人的解释,没看懂,贴一下: (a / b) % m = ( a % (m*b)) / b 笔者注:鉴于ACM题目特别喜欢M=1000000007,为质数: 当gcd(b,m) = 1, 有性质: (a/b)%m = (a*b^-1)%m, 其中b^-1是b模m的逆

HDU 4333 Revolving Digits 扩展KMP

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333 题意:给以数字字符串,移动最后若干位到最前边,统计得到的数字有多少比原来大,有多少和原来相同,有多少比原来的小. 思路:拓展KMP中的next数组标记的是子串和母串的公共前缀的长度,要将字符串长度变成原来二倍,这样如果变换后不是完全相同的数字也即公共前缀长度大于等于字符串长度,那么字母串公共前缀的下一位的大小比较就是题目所要求的比较.由于相同的数字串只算一次,则只要统计比较第一个"循环节"

扩展KMP,附上例题(HDU - 4333 Revolving Digits)

给出模板串S和串T,长度分别为Slen和Tlen,在线性时间内,对于每个S[i](0<=i<Slen),求出S[i..Slen-1]与T的 最长公共前缀长度,记为extend[i],extend[i]存放s[i]开始与T的最长公共前缀长度. 例子 a a a a a a a b b b a a a a a c extend 5 4 3 2 1 0 0 0 0 0 HDU - 4333 Revolving Digits Time Limit: 3000/1000 MS (Java/Others)

HDU 1253 胜利大逃亡 NYOJ 523【BFS】

胜利大逃亡 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 24608    Accepted Submission(s): 9427 Problem Description Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的

HDU 4771 Stealing Harry Potter&#39;s Precious dfs+bfs

Stealing Harry Potter's Precious Problem Description Harry Potter has some precious. For example, his invisible robe, his wand and his owl. When Hogwarts school is in holiday, Harry Potter has to go back to uncle Vernon's home. But he can't bring his

【HDU 4771 Stealing Harry Potter&#39;s Precious】BFS+状压

2013杭州区域赛现场赛二水... 类似“胜利大逃亡”的搜索问题,有若干个宝藏分布在不同位置,问从起点遍历过所有k个宝藏的最短时间. 思路就是,从起点出发,搜索到最近的一个宝藏,然后以这个位置为起点,搜索下一个最近的宝藏,直至找到全部k个宝藏.有点贪心的感觉. 由于求最短时间,BFS更快捷,但耗内存,这道题就卡在这里了... 这里记录了我几次剪枝的历史...题目要求内存上限32768KB,就差最后600KB了...但我从理论上觉得已经不能再剪了,留下的结点都是盲目式搜索必然要访问的结点. 在此贴

HDU 5024 Wang Xifeng&#39;s Little Plot (bfs)

Problem Description <Dream of the Red Chamber>(also <The Story of the Stone>) is one of the Four Great Classical Novels of Chinese literature, and it is commonly regarded as the best one. This novel was created in Qing Dynasty, by Cao Xueqin.

SPOJ 206 BITMAP(BFS+剪枝)

SPOJ 206 BITMAP(BFS+剪枝) ACM 题目地址:SPOJ 206 BITMAP 题意: 给出一个矩阵,有黑白点,计算每个点离最近的白点的距离,p1=(i1,j1) and p2=(i2,j2),距离d(p1,p2)=|i1-i2|+|j1-j2|. 分析: 有剪枝的BFS,如果从黑色的开始进行BFS最近的白色,复杂度是O(n^4),复杂度无法接受. 于是想把黑色白色分开记录下来,然后两遍for,发现复杂度不变... 从黑色开始搜,如果要记忆化的话,貌似很麻烦,但是我们可以从白色