A-1 Maximum Product
Given n integers a1,a2,⋯,an. For each 1≤i≤n,the maximum product for ai is defined to be pi=maxi≤j≤naiaj. Your job is to calculate the maximum products for all the n integers.
Input Specification:
Each input file contains one test case. The first line gives a positive integer n (≤105). Then n integers follow in the next line, each in the interval [−104,104].
All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in a line the maximum products of all the given n integers. All the numbers in a line must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.
Sample Input:
4
1 4 -9 6
Sample Output:
6 24 81 36
solution:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
int n;
const int N=1e5+5;
int a[N];
int ans[N];
int maxx[N],minn[N];
void output()
{
for(int i=1;i<=n;i++)
{
if(i!=1)cout<<' ';
cout<<ans[i];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
maxx[n]=a[n];
minn[n]=a[n];
for(int i=n-1;i>=1;i--)
{
maxx[i]=max(a[i],maxx[i+1]);
minn[i]=min(a[i],minn[i+1]);
}
for(int i=1;i<=n;i++)
{
if(a[i]>=0)
{
ans[i]=a[i]*maxx[i];
}
else
{
ans[i]=a[i]*minn[i];
}
}
output();
return 0;
}
A-2 The Best Grouping Balance
During the laboratary session, the teacher grouped all the students into pairs so they could help each other on their homework. The students' individual abilities are different, and the group ability is defined to be the sum of the ability values of the two students in that group. Now the teacher would like to have a grouping scheme that has the best grouping balance, that is, the difference between the maximum and minimum of all the group ability values is minimized.
Given the ability values of all the students, your job is to find this minimum difference.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive even number n (2≤n≤105), which is the number of students. The next line gives n numbers, representing the students' individual abilities (each an integer in the interval [1,108]). All the numbers in a line are separated by spaces.
Output Specification:
For each test case, output in a line the minimum of the difference between the maximum and minimum of all the group ability values, over all the possible grouping schemes.
Sample Input:
10
996 385 402 763 102 88 571 29 816 663
Sample Output:
183
solution:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
int n;
const int N=1e5+5;
int a[N];
int group[N];
int maxx=0,minn=INT_MAX;
void output()
{
for(int i=1;i<=n;i++)
{
if(i!=1)cout<<' ';
cout<<a[i];
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+1+n);
for(int i=1;i<=n/2;i++)
{
group[i]=a[i]+a[n-i+1];
maxx=max(maxx,group[i]);
minn=min(minn,group[i]);
}
cout<<maxx-minn;
}
A-3 The Farthest Distance in the World
Rabindranath Tagore wrote in "The Farthest Distance in the World":
The farthest distance in the world
is not the distance between two trees
but the branches cannot depend on each other in wind even they grow from the same root
Given a tree, the distance between a pair of nodes is the minimum number of edges one must pass when moving from one node to the other. Your job is to calculate the farthest distance between all pairs of nodes in a tree.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer n (≤104) which is the number of nodes in the tree. Hence the nodes are numbered from 1 to n. Then n numbers are given in the next line. The i-th number is the index of the parent node of the i-th node, and the parent of the only root node is −1.
Output Specification:
Print in a line the farthest distance between all pairs of nodes in the tree.
Sample Input:
13
8 4 -1 3 3 4 4 6 7 7 10 9 11
Sample Output:
7
Hint:
The farthest distance is between node 1 and node 13. The undirected path is 1, 8, 6, 4, 7, 10, 11, 13.
solution:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int N=1e4+5,M=1e7+5;
int dis[N];
int cnt=0;
int head[N];
int n,ans=0;
struct node
{
int v,w,next;
}edge[M];
void addedge(int u,int v,int w)
{
cnt++;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
int dijkstra(int s)
{
bool vis[N]={0};
priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > >q;
int curr;
for(int i=1;i<=n;i++)dis[i]=INT_MAX;
dis[s]=0;
q.push({0,s});
while(!q.empty())
{
curr=q.top().second;
q.pop();
if(vis[curr])continue;
vis[curr]=1;
for(int i=head[curr];i;i=edge[i].next)
{
if(!vis[edge[i].v] && dis[edge[i].v]>dis[curr]+edge[i].w)
{
dis[edge[i].v]=dis[curr]+edge[i].w;
q.push({dis[edge[i].v],edge[i].v});
}
}
}
int final=0;
for(int i=1;i<=n;i++)
{
if(dis[i]!=INT_MAX)final=max(final,dis[i]);
}
return final;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int u;scanf("%d",&u);
if(u!=-1)
{
addedge(i,u,1);
addedge(u,i,1);
}
}
for(int i=1;i<=n;i++)
{
int tmp=dijkstra(i);
if(tmp)ans=max(ans,tmp);
}
cout<<ans;
}
多源dijkstra堆优化暴力超时,其他做法当时时间来不及暴力骗分,有满分题解速速踢我。
A-4 Both Expensive and Inexpensive Travel Plan
As a travel itinerary(旅游行程) planner, what do you do when a customer asks you to plan a "both expensive and inexpensive" travel itinerary? Here are our suggestions:
- (1) For the customers to show off on their Wechat Moments, when there are a variety of transportation tools between a pair of cities that can be used directly, we always choose the most expensive one. For example, from Nanjing to Shanghai, we can hike, ride, take a bus, take a high-speed train, or take a plane. In this case, we should choose the plane, since it is the most expensive way.
- (2) When there are more than one route to reach the destination, we must choose the least expensive route, that is, the route with the lowest total travel expenses. Provided of course that the cost between any two adjacent cities on the route meets the requirements of (1).
- (3) When there are multiple solutions that satisfy the requirements of (2), we must choose the one that passes through the most places of interest. It is guaranteed that such a solution is unique.
Input Specification:
Each input file contains one test case. For each case, given in the first line are two positive integers: n (2≤n≤104), the number of cities, and m (≤10n), the number of routes that directly connect two cities in both directions.
The second line gives n 0's or 1's, indicating whether the corresponding city is a place of interest or not. That is, 1 at the ith position (1≤i≤n) means that the city of index i is a place of interest, and 0 means not.
Then m lines follow, each giving the two endpoints of a direct route and the travel cost in the format:
City1 City2 Cost
where the endpoint cities are numbered from 1 to n and the Cost
is a positive integer no more than 104.
The last line gives the indices of the customer's initial position and the destination, separated by a space.
Output Specification:
For each test case, first output the total cost of a "both expensive and inexpensive" travel route that satisfies the requirements given by the problem description. In the second line, output the route in the format:
Source->City1- ... ->Destination
If the solution does not exist, output Sorry
instead.
Sample Input 1:
8 16
1 0 1 1 0 1 1 0
3 2 5
4 2 10
5 2 5
6 2 10
3 7 5
7 3 20
4 7 10
5 8 5
8 5 2
5 8 10
6 8 5
1 2 5
2 1 60
7 1 10
1 7 5
1 8 15
2 1
Sample Output 1:
30
2->4->7->1
Sample Input 2:
3 1
1 1 1
1 2 1
1 3
Sample Output 2:
Sorry
solution:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int N=1e4+5,M=1e7+5;
ll dis[N];
int cnt=0;
int head[N];
int val[N];
bool vis[N];
bool flag[N];
int last[N];
//vector<vector<int> >last(N);
int n,m;
int s,t;
vector<int>ans;
struct node
{
int v,w,next;
}edge[M];
struct sm
{
int n;
int va;
};
void addedge(int u,int v,int w)
{
cnt++;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
void dijkstra()
{
memset(vis,0,sizeof vis);
//priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > >q;
priority_queue<pair<pair<int,int>,int> ,vector<pair<pair<int,int>,int> >,greater<pair<pair<int,int>,int> > >q;
int curr;
for(int i=1;i<=n;i++)dis[i]=INT_MAX;
dis[s]=0;
q.push({{0,0},s});//dis value cur
while(!q.empty())
{
curr=q.top().second;
q.pop();
if(vis[curr])continue;
vis[curr]=1;
//ans.push_back(curr);//
for(int i=head[curr];i;i=edge[i].next)
{
if(!vis[edge[i].v] && dis[edge[i].v]>=dis[curr]+edge[i].w)
{
dis[edge[i].v]=dis[curr]+edge[i].w;
val[edge[i].v]=val[curr]-flag[edge[i].v]; //+-
q.push({{dis[edge[i].v],val[edge[i].v]},edge[i].v});
//last[edge[i].v]=curr;
last[edge[i].v]=(val[edge[i].v]>val[curr])?edge[i].v:curr;
//if(curr!=edge[i].v)last[edge[i].v].push_back(curr);
//cout<<last[edge[i].v].size()<<endl;
//if(val[last[edge[i].v]]>val[curr])last[edge[i].v]=curr;
}
}
}
}
bool cmp(sm x,sm y)
{
return x.va>y.va;
}
void output()
{
for(int i=0;i<ans.size();i++)
{
if(i)cout<<"->";
cout<<ans[i];
}
}
int findmax(vector<int>a)//val /
{
/*
for(int i=0;i<a.size();i++)
{
if(i)cout<<"+++";
cout<<a[i];
}
*/
int maxx=a[0];int maxans=val[a[0]];
for(int i=1;i<a.size();i++)
{
if(val[a[i]]>maxans)
{
maxans=val[a[i]];
maxx=a[i];
}
cout<<" "<<maxx<<endl;
}
//cout<<a.size()<<endl;
//return maxx;
//sort(v.begin(),v.end,cmp);
return maxx;
}
void so()/
{
int r=t;
ans.push_back(r);
while(r!=s)
{
ans.push_back(last[r]);
r=last[r];
//r=findmax(last[r]);
}
reverse(ans.begin(),ans.end());
}
void solve()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&flag[i]);
}
map<pair<int,int> ,int>mp;
for(int i=1;i<=m;i++)
{
int a,b,x;
scanf("%d %d %d",&a,&b,&x);
if(a>b)swap(a,b);
pair<int,int>p={a,b};
if(!mp[p])mp[p]=x;
else mp[p]=max(mp[p],x);
}
//map<pair<int,int> ,int>::iterator it;
//cout<<endl;
for(auto i:mp)
{
pair<int,int>tmp=i.first;
//cout<<tmp.first<<' '<<tmp.second<<' '<<i.second<<endl;
addedge(tmp.first,tmp.second,i.second);
addedge(tmp.second,tmp.first,i.second);
}
scanf("%d %d",&s,&t);
dijkstra();
//cout<<dis[t];
if(dis[t]==INT_MAX)
{
printf("Sorry")<<endl;
}
else
{
printf("%d\n",dis[t]);
so();
output();
}
}
int main()
{
solve();
}
链式前向星配合dijistra堆优化,注意多开两个数组记录上一个节点last以及最大权值val。
第一步先用map找到链接两节点之前权值的最大值,第二部利用前向星建图(邻接表应该也可以),第三部dijkstra板子找到最短路径,第四步更新目前相同最短路径中val权值最大的点。