2020, XIII Samara Regional Intercollegiate Programming Contest (B D)
B - Bonuses on a Line
Practice link:https://vjudge.net/contest/392621#problem/B
题意:数轴上有n个点,每个点的位置为\({}_{x_{i}}\) ,你有t单位的移动距离,问你在你的移动距离内最多可以经过几个点。
思路:首先把正点和负点分开储存,然后枚举经过负点的个数,可以得到此时消耗掉的移动距离,再用二分查找可以经过正点的最大数目。
代码:
‘’‘’‘’
vector<int>v1,v2;
int main()
{
int n,t;
scanf("%d %d",&n,&t);
int p1=0,p2=0;
for(int i=1;i<=n;i++){
int num;
scanf("%d",&num);
if(num>=0){
v2.push_back(num);
}else{
v1.push_back(abs(num));
}
}
sort(v1.begin(),v1.end());
sort(v2.begin(),v2.end());
p1=v1.size();
p2=v2.size();
int maxn=0,kk=t,num;
for(int i=0;i<p1;i++){
kk=t;
num=i+1;
if(v1[i]>t)break;
kk-=2*v1[i];
int upp=upper_bound(v2.begin(),v2.end() ,kk)-v2.begin();
num+=upp;
maxn=max(maxn,num);
}
for(int i=0;i<p2;i++){
kk=t;
num=i+1;
if(v2[i]>t)break;
kk-=2*v2[i];
int upp=upper_bound(v1.begin(),v1.end() ,kk)-v1.begin();
num+=upp;
maxn=max(maxn,num);
}
printf("%d\n",maxn);
return 0;
}
D - Lexicographically Minimal Shortest Path
Practice link:https://vjudge.net/contest/392621#problem/D
题意:给你n个点,m条边的无向图,每条边都有一个字母,问你从 1 ~ n 的字典序最小的最短路。
思路:首先就是这是无权边,我们可以通过一次bfs求出每个点到 n 的最短距离,储存在dis数组中。然后我们从节点1开始,去寻找节点1的后继节点且到节点n距离为 当前节点到节点n的距离-1 的点,然后去比较其中边的字典序,去求最小的字典序,如果遇到有多个最小字典序,则把这些点都放入vector,否则vector只放字典序最小边的连点,然后在下一步继续进行这个循环,直到到达 n 点。
代码:
‘’‘’‘’
const int MAXN = 200005 ;
vector<pair<int,char>>vv[MAXN];
int n,m;
int dis[MAXN];
int fa[MAXN];
int main()
{
mem(dis,0);
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;
char c;
scanf("%d %d %c",&u,&v,&c);
vv[u].push_back(make_pair(v,c));
vv[v].push_back(make_pair(u,c));
}
mem(dis,-1);
mem(fa,-1);
dis[n]=0;
queue<int>q;
q.push(n);
while(!q.empty()){
int top=q.front();
q.pop();
for(auto i:vv[top]){
int to=i.first;
if(dis[to]==-1){
dis[to]=dis[top]+1;
q.push(to);
}
}
}
string ans;
vector<int>temp;
temp.push_back(1);
for(int i=0;i<dis[1];i++){
char minc='z'+1;
vector<int>nxt;
for(auto j:temp){
for(auto k:vv[j]){
if(dis[k.first]==dis[j]-1){
if(k.second<minc){
minc=k.second;
nxt.clear();
nxt.push_back(k.first);
fa[k.first]=j;
}else if(k.second==minc){
nxt.push_back(k.first);
fa[k.first]=j;
}
}
}
}
sort(nxt.begin(),nxt.end());
nxt.erase(unique(nxt.begin(),nxt.end()),nxt.end());
temp=nxt;
ans+=minc;
}
vector<int>path;
int pa=n;
while(pa!=-1){
path.push_back(pa);
pa=fa[pa];
}
reverse(path.begin(),path.end());
printf("%d\n",path.size()-1);
for(auto i:path){
cout<<i<<" ";
}
printf("\n");
cout<<ans;
return 0;
}
越自律,越自由