CodeForces - 346C- Number Transformation II(貪心+暴力。。)
CodeForces - 346C- Number Transformation II
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.
Examples
Input
3
3 4 5
30 17
Output
6
Input
3
5 6 7
1000 200
Output
206
- 題目大意:
給你兩個數a,b(a>b)還有一個數組c[]。問最少經過多少步可以讓a變成b。每一步可以進行兩種操作中的一種 1.a-1 2.a-a%c[i] - 解題思路;
每次找能減的最大的數,貪心的思想,一直到減到a==b為止。
先把c陣列排序,每次找能減的最大的數
for(int i=n-1;i>=0;i--)//找一個減的最多的
{
if(a-a%c[i]>=b)
tmp=min(tmp,a-a%c[i]);
}
然後就有個小小的提速的方法。就是如果當前的a-a%c[n]<b的話,那麼這個c[n]在後面就沒用了,就可以直接摘除了。
while(n>0)//去掉不可能的
{
if(a-a%c[n-1]<b)
n--;
else
break;
}
還有個地方很坑,,,就是c陣列需要去重,不然就一直T。。。
n = unique(c,c+n)-c;
總之,,我感覺這個題蠻坑的,1e5的n,然後每次都掃一遍更新一下,每次掃一遍。。。a,b之間差1e6,極端的情況會掃很多很多次把,我一直在找規律,找了很久也沒找出來,看了題解發現竟然是暴力。。可能是我太菜了。
- AC程式碼:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
const int maxn=1e5+10;
int n,a,b;
int c[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&c[i]);
sort(c,c+n);
n = unique(c,c+n)-c;
scanf("%d%d",&a,&b);;
int tmp;
int cnt=0;
while(a>b)
{
tmp=a-1;//a可以直接減一
for(int i=n-1;i>=0;i--)//找一個減的最多的
{
if(a-a%c[i]>=b)
tmp=min(tmp,a-a%c[i]);
}
a=tmp;
cnt++;
if(a==b)
break;
while(n>0)//去掉不可能的
{
if(a-a%c[n-1]<b)
n--;
else
break;
}
}
// cout<<cnt<<endl;
printf("%d\n",cnt);
return 0;
}