2018今日头条杯 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.

题意:给你m个数字,任意用组成离n最近的数与n相差多少

估计我一辈子都想不到用图论来做吧,只能说一句膜拜队友。

题解:从m个数字中任意选一个数字作为mod(选最小b[i]时最优),dis[i]表示从 取模余数为0的点取模余数为i的点 的最短路

很明显,m个数字任意取得到的数字可以写成 dis[i] + k*mod (k为常数, 0 < i < m)

那么我们就是比较 n 与 dis[i] + k*mod 了

当 dis[i] <= n 的时候

很明显,看起来我们只需要(n - dis[i])%mod 就行了,然而非也,因为n是可以大于dis[i] + k*mod的,所以必须在求一个mod-(n - dis[i])%mod的值,二者取min

dis[i] > n 的时候

很明显,你只能跑那么远再回来了 dis[i] - n (这里不写能水过去!!!惊了)

OK,上代码

#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]){
				minn = 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] = minn + edge[u][j].d;
		}
	}
}


int main()
{
//    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);
            ans = min(ans,y);
        }
        else{
            ans = min(ans,dis[i]-n);
        }
    }
    cout<<ans<<endl;
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/Tokisaki-Kurumi-/p/8856132.html