Codeforces Round #201 (Div. 2). E--Number Transformation II(贪心)
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Description
You are given a sequence of positive integers x1, x2, ..., xn and two non-negative integers a and b. Your task is to transform a into b. To do that, you can perform the following moves:
- subtract 1 from the current a;
- subtract a mod xi(1 ≤ i ≤ n) from the current a.
Operation a mod xi means taking the remainder after division of number a by number xi.
Now you want to know the minimum number of moves needed to transform a into b.
Input
The first line contains a single integer n (1 ≤ n ≤ 105). The second line contains n space-separated integers x1, x2, ..., xn (2 ≤ xi ≤ 109). The third line contains two integers a and b (0 ≤ b ≤ a ≤ 109, a - b ≤ 106).
Output
Print a single integer — the required minimum number of moves needed to transform number a into number b.
Sample Input
Input
3
3 4 5
30 17
Output
6
Input
3
5 6 7
1000 200
Output
206
题意:
给出n个数,以及a跟b,你有两种操作,要么a-1,要么a-a%x[i],问最终由a变到b需要多少步
思路:
一开始以为是数论之类的题目,不敢用暴力写,但在看了题解之后发现用暴力贪心再加一个小剪枝就完全能过。。。
由于元素有可能重复,所以需要对所有元素去重。
然后得知道一点,如果a-a%x[i]如果小于b,那以后无论如何变a-a%x[i]仍然会小于b,所以x的个数会逐渐递减。
接下来就是贪心,每次取a-1跟a-a%x[i]最小的数,直到a==b
这里有一个小细节,我第一次交的时候,在二层循环内部是用的两个max处理的(见注释掉的部分),然后挂掉了。。。。
然后我改成了一个min,就AC了,
以后能够简化运算的地方一定要简化,特别是循环内部
代码:
#include<bits/stdc++.h> using namespace std; const int MAXN=1e5+3; int m[MAXN]; int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); //freopen("data.in","r",stdin); int a,b; int n; cin>>n; for(int i=0;i<n;i++){ cin>>m[i]; } cin>>a>>b; sort(m,m+n); int len=unique(m,m+n)-m; int res=0; int now=-1; while(a>b){ //now=a-1; now=a-1; for(int i=0;i<len;i++){ if(a-a%m[i]<b){ m[i--]=m[--len]; } else{ // now=max(now,a%m[i]); // now=max(now,1); now=min(now,a-a%m[i]); } } //a-=now; a=now; res++; } cout<<res<<endl; }