With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.
Input Specification:
Each input file contains one test case. For each case, the first line contains 4 positive numbers: C
max(≤ 100), the maximum capacity of the tank; D (≤30000), the distance between Hangzhou and the destination city; Davg(≤20), the average distance per unit gas that the car can run; and N (≤ 500), the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: Pi, the unit gas price, and Di (≤D), the distance between this station and Hangzhou, for i=1,⋯,N. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print The maximum travel distance = X where X is the maximum possible distance the car can run, accurate up to 2 decimal places.
Sample Input 1:
50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300
Sample Output 1:
749.17
Sample Input 2:
50 1300 12 2
7.10 0
7.00 600
Sample Output 2:
The maximum travel distance = 1200.00
试题大意:
汽⻋从杭州出发可以通过⾼速公路去任何城市,但是油箱的容量是有限的,路上有很多加
油站,每个加油站的价格不同,为汽⻋设计⼀个从杭州到终点的最便宜的路线, Cmax表示油箱最⼤容
量, D表示杭州到⽬的地的距离, Davg表示平均每单位的汽油可以让汽⻋⾏驶的距离, N表示汽⻋的站
点数量,每个站点都会给出它的单位油价Pi和汽⻋站点和杭州的距离Di,求汽⻋从杭州到终点的最⼩
花费,如果不能够到达,就输出汽⻋能够⾏驶的最⼤距离
主要思路
易错
#include
#include
#include
using namespace std;
int n;
double c,d,vd;
struct Move{
double p;
double l;
}car[510];
const double INF = 9999999.99;
double maxd;
double now ,nowrest ,ansp ,ansl;
bool cmp(Move a,Move b){
if(a.l == b.l) return a.p<b.p;
else return a.l<b.l;
}
void add1(int a,int b){
ansl += car[a].l-car[b].l-nowrest;
ansp += (car[a].l-car[b].l-nowrest)/vd*car[b].p;
nowrest = 0;
}
void add2(int a,int b){
ansl += maxd;
ansp += (maxd-nowrest)/vd*car[b].p;
nowrest = maxd-(car[a].l-car[b].l); //开车到下一个加油站的剩余可以行驶的距离
}
int juge(int index){
bool flag = false;
double pricemine = INF;
int pid = -1;
for(int i=index+1;i<=n&&car[i].l-car[index].l<=maxd;i++){
if(pricemine>car[i].p){
pid = i;
pricemine = car[i].p;
if(pricemine < car[index].p) {
flag = true;
add1(pid,index);
index = pid;
break;
}
}
}
if(pricemine == INF) return -1;
else if(!flag) {
add2(pid,index);
index = pid;
}
return index;
}
int main(){
scanf("%lf%lf%lf%d",&c,&d,&vd,&n);
maxd = c*vd;
car[0].l = d;car[0].p = 0;
for(int i=1;i<=n;i++){
scanf("%lf%lf",&car[i].p,&car[i].l);
}
sort(car,car+n+1,cmp);
if(car[0].l != 0) printf("The maximum travel distance = 0.00\n");
else{
now = 0.0,nowrest = 0.0,ansp = 0.0,ansl = 0.0;
while(now <n){
now = juge(now);
if(now == -1) break;
}
if(now == -1) printf("The maximum travel distance = %.2f\n",ansl+maxd);
else printf("%.2f\n",ansp);
}
return 0;
}
Given any permutation of the numbers {0, 1, 2,…, N−1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:
Swap(0, 1) => {4, 1, 2, 0, 3}
Swap(0, 3) => {4, 1, 2, 3, 0}
Swap(0, 4) => {0, 1, 2, 3, 4}
Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.
Input Specification:
Each input file contains one test case, which gives a positive N (≤105) followed by a permutation sequence of {0, 1, …, N−1}. All the numbers in a line are separated by a space.
Output Specification:
For each case, simply print in a line the minimum number of swaps need to sort the given permutation.
Sample Input:
10
3 5 7 2 6 4 9 0 8 1
Sample Output:
9
试题题解
给出⼀个n个数的序列,数字为0~n-1的乱序,每次⽤两两交换的⽅式⽽且只能⽤0和另⼀个数交换,使序列变成有序的,问最少需要多少步骤。
试题易错
超时,在判断是否已经配对完全时,需要遍历访问数组,指数级则会超时。
#include
#include
using namespace std;
set <int> st;
const int mmax = 100010;
int a[mmax],n,table[mmax];
int main(){
scanf("%d",&n);
int count = 0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
table[a[i]] = i;
st.insert(i);
}
int index = table[0],t=0;
while(1){
if(index == 0){
for(set<int>::iterator it = st.begin();it!=st.end();it++){
if(table[a[*it]]!=a[*it]&&a[*it]!=0) { //从第一个没有配对的开始,否是会超时
index = *it;
table[a[*it]] = 0;
t = table[*it];
count++;
break;
}
}
if(index==0) break;
}
else{
t = table[index];
}
table[index] = index;
st.erase(index);//删除已经配对好的元素
//printf("table[%d] = %d\n",index,index);
index = t;
count++;
}
printf("%d\n",count);
return 0;
}
#include
#include
using namespace std;
const int mmax = 100010;
int n;
int a[mmax],t;
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&t);
a[t] = i;
}
int count = 0;
for(int i=1;i<n;i++){
if(a[i]!=i){
while(a[0]!=0){
swap(a[0],a[a[0]]); //直接使用swap交换后,让顺序替换
count++;
}
if(i!=a[i]){
swap(a[0],a[i]);
count++;
}
}
}
printf("%d\n",count);
return 0;
}
Given a collection of number segments, you are supposed to recover the smallest number from them. For example, given { 32, 321, 3214, 0229, 87 }, we can recover many numbers such like 32-321-3214-0229-87 or 0229-32-87-321-3214 with respect to different orders of combinations of these segments, and the smallest number is 0229-321-3214-32-87.
Input Specification:
Each input file contains one test case. Each case gives a positive integer N (≤104 ) followed by N number segments. Each segment contains a non-negative integer of no more than 8 digits. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the smallest number in one line. Notice that the first digit must not be zero.
Sample Input:
5 32 321 3214 0229 87
Sample Output:
22932132143287
试题大意
给⼀些字符串,求它们拼接起来构成最⼩数字的⽅式
#include
#include
#include
#include
using namespace std;
const int mMax = 10010;
string s[mMax];
int n;
bool cmp(string a,string b){
return a+b < b+a; //相加直接拼接
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>s[i];
}
sort(s,s+n,cmp);
string ans;
for(int i=0;i<n;i++){
ans += s[i];
}
while (ans[0]=='0'&&ans.length()!=0){
ans.erase(ans.begin());
}
if(ans.length() == 0) cout<<0<<endl;
else cout<<ans<<endl;
return 0;
}
因为是集合所以有着互异性,set里面的各元素是各不相同的,而且set会按照元素进行从小到大排序。
set
set
只能通过迭代器访问,例如:set
for(set \<int> ::iterator it = s.begin();it!= s.end(
;it++){
printf("%d",*it)
}
或者,将set
for (int i = 0; i < 6; i++) {
s.insert(i); // 向集合s⾥⾯插⼊i
}
*(s.find(2)) // 如果2存在,则printf 结果为2。
s.find(2)!=s.end() // 判断该元素是否存在
勉励
加油
贪心,思路清晰很重要!!!