链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=978
题目大意:
在夜晚有n个人过桥,但是只有一个手电筒,所以每次只能两个人过去,然后过去的一个人再把手电筒带过来,依次进行,知道所有人都过去。由于每个人的过桥速度不同,所以每一组的速度取决与较小的那个。求最快多久全过去,并且输出方案。
思路:
当n=1时,只有一个人,直接过去
当n=2时,两个一起过。
当n=3时,设A,B,C三人,A 速度最快,那么方案为:
A B
A
A C
当n>3时, 所有人按速度从小到大排列,第一,二个为A,B,最后两个为X,Y,那么为了让X,Y过去,有两种方案:
方案一:
A B
A
X Y
B
总时间为A+2*B+Y
方案二:
A X
A
A Y
A
总时间为2*A+X+Y,
如果A+2*B+Y < 2*A+X+Y,那么选择第一种方案,否则第二种
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cctype>
#include<vector>
using namespace std;
const int maxn = 1010;
int arr[maxn];
int path[maxn][3];
int main(){
int T;
bool first=true;
scanf("%d", &T);
while(T--){
if(first) first=false;
else puts("");
int n;
scanf("%d", &n);
for(int i=0; i<n; ++i) scanf("%d", &arr[i]);
sort(arr, arr+n);
if(n==1){
printf("%d\n%d\n",arr[0],arr[0]);
continue;
}else if(n==2){
printf("%d\n", arr[1]);
printf("%d %d\n",arr[0],arr[1]);
continue;
}else if(n==3){
printf("%d\n",arr[1]+arr[2]+arr[0]);
printf("%d %d\n",arr[0], arr[1]);
printf("%d\n", arr[0]);
printf("%d %d\n",arr[0], arr[2]);
continue;
}
deque<int>Q;
Q.clear();
for(int i=1; i<n; ++i)
Q.push_back(arr[i]);
int pos=0;
int fast=arr[0];
int sum = 0;
while(Q.size() >= 3){
int front=Q.front(), back=Q.back();
Q.pop_back();
if(fast+front*2+back < fast*2+back+Q.back()){
sum += fast+front*2+back;
path[pos][0] = fast;
path[pos][1] = front;
path[pos++][2] = fast;
path[pos][0] = Q.back();
path[pos][1] = back;
path[pos++][2] = front;
}else{
sum += fast*2+back+Q.back();
path[pos][0] = fast;
path[pos][1] = back;
path[pos++][2] = fast;
path[pos][0] = fast;
path[pos][1] = Q.back();
path[pos++][2] = fast;
}
Q.pop_back();
}
if(Q.size() == 1){
sum += Q.back();
path[pos][0] = fast;
path[pos][1] = Q.back();
path[pos++][2] = -1;
}else if(Q.size() == 2){
sum += Q.front()+Q.back()+fast;
path[pos][0] = fast;
path[pos][1] = Q.back();
path[pos++][2] = fast;
path[pos][0] = fast;
path[pos][1] = Q.front();
path[pos++][2] = -1;
}
printf("%d\n", sum);
for(int i=0; i<pos; ++i){
printf("%d %d\n", path[i][0],path[i][1]);
if(path[i][2] != -1)printf("%d\n", path[i][2]);
}
}
return 0;
}