第一个是判断 给你 n 个数,问a 是否能由求和求到,求出每一个数%最小的数的最小出现值,比较大小即可,用最短路建图
#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
const int INF = 0x3f3f3f3f ;
ll save[5050] ;
ll dis[50050] ;
ll point , road , mod ;
struct node{
ll point , dis ;
node(int _p = 0 , int _d = 0 ) : point (_p) , dis (_d) { }
bool operator < ( const node & k ) const {
return dis > k.dis ;
}
};
///dis == min value
bool vis[50050];
void dij(){
memset(vis , 0 , sizeof(vis)) ;
for(int i = 0 ; i <= point ; i ++ ) dis[i] = INF ;
dis[0] = 0 ;
priority_queue<node> pq ;
//while( ! pq.empty() ) pq.pop() ;
pq.push(node(0 , 0)) ;
node temp ;
while( ! pq.empty() ){
temp = pq.top() ; pq.pop() ;
ll u = temp.dis , st = temp.point ;
if(vis[st]) continue ;
vis[st] = true ;
for(int i = 0 ; i < road ; i ++ ){
ll cost = save[i] ;
ll ed = (st + cost) % mod ;
if(! vis[ed] ){
dis[ed] = min(dis[ed] , dis[st] + cost) ;
pq.push(node(ed , dis[ed])) ;
}
}
}
}
int main(){
int k ;
while( ~ scanf("%d" , &k )){
for(int i = 0 ; i < k ; i ++ ){
scanf("%lld" , &save[i]) ;
}
//sort(save , save + k ) ;
mod = save[0] ;
point = save[0] , road = k ;
memset(dis , 0 , sizeof(dis)) ;
dij() ;
int op ; scanf("%d" , &op) ;
ll re ;
while( op -- ){
scanf("%lld" , &re) ;
if( dis[re % mod] <= re ) puts("TAK") ;// puts("Yes") ;
else puts("NIE") ; //puts("No") ;
}
}
return 0 ;
}
航电多校的lazy running
注意数据范围
#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
const int INF = 0x3f3f3f3f ;
ll save[5050] ;
ll dis[50050] ;
ll point , road , mod ;
struct node{
ll point , dis ;
node(int _p = 0 , int _d = 0 ) : point (_p) , dis (_d) { }
bool operator < ( const node & k ) const {
return dis > k.dis ;
}
};
///dis == min value
bool vis[50050];
void dij(){
memset(vis , 0 , sizeof(vis)) ;
for(int i = 0 ; i <= point ; i ++ ) dis[i] = INF ;
dis[0] = 0 ;
priority_queue<node> pq ;
while( ! pq.empty() ) pq.pop() ;
pq.push(node(0 , 0)) ;
node temp ;
while( ! pq.empty() ){
temp = pq.top() ; pq.pop() ;
ll u = temp.dis , st = temp.point ;
if(vis[st]) continue ;
vis[st] = true ;
for(int i = 0 ; i < road ; i ++ ){
ll cost = save[i] ;
ll ed = (st + cost) % mod ;
if(! vis[ed] ){
dis[ed] = min(dis[ed] , dis[st] + cost) ;
pq.push(node(ed , dis[ed])) ;
}
}
}
}
ll lazy[5] ;
int main(){
int kase ; scanf("%d" , &kase) ;
while( kase -- ){
ll min_num ; scanf("%lld" , &min_num) ;
for(int i = 0 ; i < 4 ; i ++ ){
scanf("%lld" , &lazy[i]) ;
}
save[0] = 2 * lazy[0] ;
save[1] = 2 * (lazy[0] + lazy[3]) ;
save[2] = save[1] + 2 * lazy[2] ;
save[3] = lazy[0] + lazy[1] + lazy[2] + lazy[3] ;
save[4] = 2 * lazy[1] ;
save[5] = save[4] + 2 * lazy[2] ;
save[6] = save[5] + 2 * lazy[3] ;
sort(save , save + 7 ) ;
road = 7 ;
mod = save[0] ;
point = save[0] ;
dij() ;
ll ans = INF ;/*
for(int i = 0 ; i < point ; i ++ ){
for(int j = 0 ; j < 7 ; j ++ ){
(min_num - dis[i]) / save[j] + dis[i]
}
ans = (min_num / )
}*/
for(int i = min_num ; ; i ++ ){
if(i >= dis[i % mod]){
ans = i ;
break ;
}
}
printf("%d\n" , ans) ;
}
return 0 ;
}