做法:
1.直接建图跑最短路,按照字典序规则。但建图需要花很多的空间,只能过前两个子任务。第三个MLE
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1e6+10;
const int mode=998244353;
const int inf=0x3f3f3f3f;
typedef long long ll;
int n,m;
string s;
map <int,string> mp;
struct edge{
int u,v,next;
string w;
}e[maxn<<1];
int head[maxn],cnt=0;
struct DS{
string s;
int u;
bool operator < (const DS&rhs) const{
int l1=s.length();
int l2=rhs.s.length();
int l=min(l1,l2);
for (int i=0;i<l;i++){
if(s[i] < rhs.s[i]) return false;
else if(s[i] > rhs.s[i]) return true;
else{
continue;
}
}
if (l == l1) return false;
else return true;
}
DS(string str,int uu):s(str),u(uu){}
};
void add(int u,int v){
e[++cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt;
}
int change_to_int(string s){
int sum = 0;
int f = 100000;
for (int i=0;i<s.length();i++){
sum += (s[i]-'0') * f;
f/=10;
}
return sum;
}
void init(){
int l = s.length();
for (int i=0; i<l;i+=12){
string sub1 = s.substr(i,6);
string sub2 = s.substr(i+6,6);
int u = change_to_int(sub1);
int v = change_to_int(sub2);
add(u,v);
add(v,u);
if(mp[u] == "") mp[u] = sub1;
if(mp[v] == "") mp[v] = sub2;
}
}
string str_d[maxn];
ll d[maxn];
bool vis[maxn];
void solve(){
for (int i=0;i<n;i++){
str_d[i] = "9";
d[i] = inf;
vis[i] = 0;
}
str_d[0] = "000000";
d[0] = 0;
priority_queue<DS> q;
q.push(DS(mp[0],0));
while(!q.empty()){
DS ds= q.top();
int u = ds.u;
string sub = ds.s;
q.pop();
if (vis[u]) continue;
vis[u] = true;
for (int i=head[u];i;i=e[i].next){
int v=e[i].v;
// if(vis[v]) continue;
string temp = sub + mp[v];
if(str_d[v].compare(temp) > 0) {
str_d[v] = temp;
q.push(DS(str_d[v],v));
d[v] = (1000000 *d[u] + v) % mode;
}
}
}
}
void print(){
for (int i=1;i<n;i++){
if(d[i] == inf) puts("-1");
else{
printf("%lld\n",d[i]);
}
}
}
int main(){
scanf("%d%d",&n,&m);
getchar();
getline(cin,s);
init();
solve();
print();
return 0;
}
/*
5 5
000000000003000001000003000001000002000002000000000002000003
*/
2.正解:用优先队列存图,每次取队列中序号最小的那个点,则可以保证字符串连接时候的字典序最小。然后从0点跑dfs,第一次到任何一个点时候的路径即为点0到这个点的路径最小值。(很神奇的建图方法)
#include
using namespace std;
const int maxn=1e6+10;
const int mode=998244353;
const int inf=0x3f3f3f3f;
typedef long long ll;
string s;
int n,m;
ll d[maxn];
bool vis[maxn];
priority_queue<int,vector<int>,greater<int> > Map[maxn];
void dfs(int x,ll dis){
while(!Map[x].empty()){
int v = Map[x].top();
Map[x].pop();
if(vis[v]) continue;
ll temp = (dis*1000000 + v) % mode;
vis[v] = true;
d[v] =temp;
dfs(v,temp);
}
}
int change_to_int(string s){
int sum = 0;
int f = 100000;
for (int i=0;i<s.length();i++){
sum += (s[i]-'0') * f;
f/=10;
}
return sum;
}
void init(){
int l = s.length();
for (int i=0; i<l;i+=12){
string sub1 = s.substr(i,6);
string sub2 = s.substr(i+6,6);
int u = change_to_int(sub1);
int v = change_to_int(sub2);
Map[u].push(v);
Map[v].push(u);
}
}
int main(){
cin>>n>>m;
getchar();
getline(cin,s);
for (int i=1;i<n;i++) {
d[i] = inf;
vis[i] = 0;
}
vis[0] = true;
init();
dfs(0,0);
for (int i=1;i<n;i++){
if(d[i] == inf) puts("-1");
else printf("%lld\n",d[i]);
}
return 0;
}
#include
using namespace std;
typedef long long ll;
const int Maxn = 1e5+10;
const int Inf = 0x7f7f7f7f;
const int Mod = 1e9+7;
int a[Maxn],v[Maxn];
int l_0[Maxn],r_1[Maxn];
double ans[Maxn];
int _1[Maxn],tol1,_0[Maxn],tol0;
int main(){
int n,l;
scanf("%d %d",&n,&l);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&v[i]);
for(int i=1;i<=n;i++)
if( v[i] == 1 )
r_1[i] = r_1[i-1] + 1,_1[++tol1] = a[i];
else r_1[i] = r_1[i-1];
for(int i=n;i>=1;i--)
if( v[i] == 0 )
l_0[i] = l_0[i+1] + 1,_0[++tol0] = a[i];
else l_0[i] = l_0[i+1];
for(int i=1;i<=n;i++)
{
double time,dis;
int dir;
if( v[i] == 1 )
{
if( l_0[i] >= r_1[i] )
{
int tmp = l_0[i] - r_1[i];
dir = 0;
dis = 1.0*(_1[1] + _0[tmp + 1])/2;
time= -1.0*(_1[1] - _0[tmp + 1])/2;
}
else
{
int tmp = r_1[i] - l_0[i];
dir = 1;
dis = 1.0*(_1[tmp] + _0[1])/2;
time= -1.0*(_1[tmp] - _0[1])/2;
}
}
else
{
if( r_1[i] >= l_0[i] )
{
int tmp = r_1[i] - l_0[i];
dir = 1;
dis = 1.0*(_1[tmp+1] + _0[1])/2;
time= -1.0*(_1[tmp+1] - _0[1])/2;
}
else
{
int tmp = l_0[i] - r_1[i];
dir = 0;
dis = 1.0*(_1[1] + _0[tmp])/2;
time= -1.0*(_1[1] - _0[tmp])/2;
}
}
if( dir == 0 ) ans[i] = time + dis;
else ans[i] = time + l-dis;
}
for(int i=1;i<=n;i++)
printf("%lld ",(ll)(ans[i]+0.5));
return 0;
}