2018 Toutiao Cup E-Jump a Jump

Problem E. Jump A Jump
Input file: standard input
Output file: standard output
Time limit: 1 seconds
Memory limit: 512 mebibytes

There’s a very popular game called jump a jump recently.In order to get good marks, many people spend a lot of
time in this game.Wei is the master of jump a jump,he can easily get a very high score every time.
Recently he discovered that because of his muscle memory,he could not fully control his game score.
Now he wants you to help him figure out the nearest score that he can get from his desired score.
Every time he jumps, he chooses one from m distances,he can jump until he wants to end,and he can also use every
distance any times.
Input
The first line has a number n(0 < n ≤ 1015) to indicate the score he desired.
The next line has a number m(0 < m ≤ 2000), which indicates how many choices each step has.
The last line has m integers bi(0 < bi ≤ 5000) representing the ith distances.
Output
Output is the absolute value of the difference between the nearest score he can get and his desired score.
Examples
standard input standard output
11
3
5 7 8

1

Note
In the example,
He can jump 5 + 7 = 12, 12 − 11 = 1.
He can also jump distance 5 for two times, and 2 × 5 = 10, 11 − 10 = 1.

The meaning of the question: give you m numbers, use any number that is closest to n and how much is the difference between n

It is estimated that I will never think of using graph theory to do it in my life. I can only say that I admire my teammates.

Problem solution: Choose any number from m numbers as mod (optimal when choosing the smallest b[i]), dis[i] represents the shortest path from the point where the modulo remainder is 0 to the point where the modulo remainder is i

Obviously, the arbitrary number obtained by m numbers can be written as dis[i] + k*mod (k is a constant, 0 < i < m)

Then we are comparing n with dis[i] + k*mod

when dis[i] <= n

Obviously, it seems that we only need (n - dis[i])%mod, but no, because n can be greater than dis[i] + k*mod, so we must find a mod-(n - dis[i])%mod value, both take min

when dis[i] > n

Obviously, you can only run so far and come back dis[i] - n

 

OK, on ​​the code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const long long maxn = 5010;
const long long INF = 0x3f3f3f3f3f3f3f3f;
long long vis[maxn];
long long dis[maxn];
long long n,m,mod;
long long b[maxn];

struct node
{
	long long x,d;
	node();
	node(long long xx,long long dd){
		x = xx;
		d = dd;
	}
};

vector<node> edge[maxn];

void dijkstra(long long x)
{
	long long i,j;
	for(i=0;i<mod;i++) vis[i] = 0,dis[i] = INF;
	dis[x] = 0;

	for(i=0;i<mod;i++){
		long long minn = INF;
		long long u = 0;
		for(j=0;j<mod;j++){
			if(!vis[j] && minn > dis[j]){
				from = dis [j];
				u = j;
			}
		}
        vis [u] = 1;
		for(j=0;j<edge[u].size();j++){
            long long v = edge[u][j].x;
			if(!vis[v] && (minn + edge[u][j].d) < dis[v])
				dis [v] = from + edge [and] [j] .d;
		}
	}
}


intmain()
{
//    freopen("in.txt","r",stdin);
	cin>>n>>m;
	mod = maxn;
	for(long long i=1; i<=m; i++){
        scanf("%d",&b[i]);
        mod = min (b [i], mod);
	}
    for(long long i=0; i<mod; i++){
        for(long long j=1; j<=m; j++){
            edge[i].push_back(node((b[j]+i)%mod,b[j]));
        }
    }
    dijkstra(0);

    long long ans = maxn;

    for(long long i=0; i<mod; i++){
        if(dis[i] < n){
            long long x = (n-dis[i])%mod;
            long long y = min(x,mod-x);
            years = min(years,y);
        }
        else{
            years = min(years,dis[i]-n);
        }
    }
    cout<<ans<<endl;
	return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324460660&siteId=291194637