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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43179892/article/details/84823833