0
点赞
收藏
分享

微信扫一扫

ACM练习题C++版答案记录-Section 3


最近复习C++,拿起ACM从头练,在此做个答案记录,大家不要盲目复制哦,要有自己的思考哦

练习地址:​​http://acm.hdu.edu.cn/userlo​​

总体上,section3部分我花了不少时间呢,如果想破脑袋也想不到好办法,可以去查阅网上的各种方法,不要局限于自己的编程哦,做出来的题目,多看看别人的解答,也会有好处

1.3.1 排名问题花了些心思,复习了struct结构体的使用方法,编程过程中有两个注意点

  • 变量不能用于定义数组长度,试了很多次都不行,提交会显示 ​​Compilation Error​​
  • 如果提交出现了Time Limit Exceeded问题,可能不是因为你采用的排序方法问题,而是其他方面还需要优化,我觉得1000元素以内采用冒泡排序问题不大,所以就在数组长度上优化了一下,将未通过的同学直接排除出原数组,这里不建议声明新的数组,因为这样也很耗时,也会出现Time Limit Exceeded问题

//1.3.1 排名
#include<string>
#include<iostream>
using namespace std;
/**
输入:
人数 题数 分数线
各题分值
准考证号 解决的题数 对应的题号
第一行输入为0时结束

输出:
通过的考生人数
通过的考生考号 分数
注:分数从高到低,分数相同时按考号排
*/
typedef struct student
{
string number; // 准考证号
int total_score; // 个人总分
int num; // 准考证号后几位的数字
} student;
int main()
{
int std_count, exam_count, pass_score; // 人数 题数 分数线
int solve_num, pass_count;
while(cin>>std_count)
{
if(std_count == 0)
{
break;
}
cin>>exam_count>>pass_score;
int exam_points[10]; // 各题分值
for(int i=0; i<exam_count; i++)
{
cin>>exam_points[i];
}
struct student std[1000]; // 声明一批学生变量
pass_count = 0;
for(int i = 0; i < std_count; i++)
{
cin>>std[i].number>>solve_num;
std[i].total_score = 0;
std[i].num = -1;
int a;
while(solve_num--)
{
cin>>a;
std[i].total_score += exam_points[a-1];
}
// cout<<"第"<<i<<"位考生的总成绩是total_score = "<<std[i].total_score<<endl;
if(std[i].total_score >= pass_score)
{
// cout<<"total_score >= "<<pass_score<<endl;

pass_count++;
string num1 = std[i].number.substr(2);
std[i].num = 0;
for(int j = 0 ; j < num1.length(); j++)
{
std[i].num = std[i].num * 10 + (num1[j] - 48);
}
std[pass_count - 1] = std[i];
// cout<<std[i].num<<endl;
}
}
cout<<pass_count<<endl;


struct student std_temp;
for(int i = 0; i < pass_count - 1; i++)
{
for(int j = pass_count - 1; j > i; j--)
{
if((std[j].total_score > std[j-1].total_score)
|| (std[j].total_score == std[j-1].total_score && std[j].num < std[j-1].num))
{
std_temp = std[j];
std[j] = std[j-1];
std[j-1] = std_temp;
}
}
}

for(int i = 0; i < pass_count; i++)
{
cout<<std[i].number<<" "<<std[i].total_score<<endl;
}
}
return 0;
}

1.3.2 百步穿杨

#include<string>
#include<iostream>
using namespace std;
/**
要箭的人数
要箭的种类数
种类 个数
*/
int main()
{
int person_num;
int type, count, arrow[10];
cin>>person_num;
int arr[30];
while(person_num--)
{
for(int i = 0; i < 30; i++)
{
arr[i] = 0;
}
int kinds;
cin>>kinds;
while(kinds--)
{
cin>>type>>count;
arr[type] = count;
}
for(int i = 0; i < 30; i++)
{
if(arr[i] != 0)
{
string arrow = ">+";
type = i - 2;
while(type--)
{
arrow += "-";
}
arrow += "+>";
count = arr[i];
while(count--)
{
cout<<arrow<<endl;
}
cout<<endl;
}
}
}
return 0;
}

1.3.3 排序

#include<string>
#include<iostream>
using namespace std;

int main()
{
string str_num;
while(cin>>str_num)
{
int len = str_num.length();
if(len == 0)
{
break;
}
int num[500], count = 0;
for(int i = 0; i < 500; i++)
{
num[i] = -1;
}
for(int i =0; i < len; i++)
{
if(str_num[i] != '5')
{
if(num[count] == -1)
{
num[count]++;
}
num[count] = num[count] * 10 + (str_num[i] - 48);
}
else
{
if(num[count] != -1)
{
// cout<<num[count]<<" ";
count++;
}
}
}
if(num[count] != -1)
{
// cout<<num[count]<<endl;
count++;
}


//冒泡排序
for(int i = 0; i < count - 1; i++)
{
for(int j = count - 1; j > i; j--)
{
if(num[j] < num[j-1])
{
num[j] = num[j] ^ num[j-1];
num[j-1] = num[j] ^ num[j-1];
num[j] = num[j] ^ num[j-1];
}
}
}

for(int i = 0; i < count - 1; i++)
{
cout<<num[i]<<" ";
}
cout<<num[count - 1]<<endl;
}

return 0;
}

1.3.4 Save HDU 题目看错了浪费不少时间,参考了别人的代码终于做出来了,学会了sort排序,不用每次都自己写排序算法啦

还学到了一个语句,可以加速输入输出的,目前没看出什么效果啦,先用着

#include<iostream>
#include<algorithm>
using namespace std;

/**
输入:
口袋的容量 宝贝的种类
某种宝贝的单价 宝贝对应的体积
输出:
可带走的最大价值量
*/
struct jewelry
{
int cap;
int pri;
};
bool compare(jewelry j1, jewelry j2)
{
return j1.pri > j2.pri; //大于号为降序,小于号为升序
}
int main()
{
int capacity, kinds;
struct jewelry jewelries[100];
while(cin>>capacity && capacity != 0)
{
cin>>kinds;
for(int i = 0; i < kinds; i++)
{
cin>>jewelries[i].pri>>jewelries[i].cap;
}
//排序
sort(jewelries, jewelries+kinds, compare);

// for(int i = 0; i < kinds; i++)
// {
// cout<<jewelries[i].pri<<" "<<jewelries[i].cap<<endl;
// }

//计算
int total_cap = 0;
int value = 0;
for(int i = 0; i < kinds; i++)
{
if(capacity > jewelries[i].cap)
{
value += jewelries[i].pri * jewelries[i].cap;
capacity -= jewelries[i].cap;
}
else
{
value += jewelries[i].pri * capacity;
break;
}
}
cout<<value<<endl;
}
return 0;
}

1.3.5 买大米       和1.3.4如出一辙,上一题会了,下一题也非常简单了

这题我学会了采用setprecision来精确小数位数

#include<algorithm>
#include<iostream>
#include<iomanip>
using namespace std;

/**
输入:
测试用例数量
有限金额 大米的种类
某种大米的单价 大米的重量
输出:
可买到的最大重量,保留两位小数
*/
struct rice2
{
int price;
int weight;
};
bool compare(rice2 r1, rice2 r2)
{
return r1.price < r2.price; // 按价格升序
}
int main()
{
int n, money, kinds;
cin>>n;
for(int k = 0; k < n; k++)
{
cin>>money>>kinds;
struct rice2 rice[1000];
for(int i = 0; i < kinds; i++)
{
cin>>rice[i].price>>rice[i].weight;
}
//排序
sort(rice, rice + kinds, compare);

// for(int i = 0; i < kinds; i++)
// {
// cout<<rice[i].price<<" "<<rice[i].weight<<endl;
// }

double total_weight = 0.0;
double total_money = money;

for(int i = 0; i < kinds; i++)
{
double a = rice[i].price * rice[i].weight;
if(total_money > a)
{
total_weight += rice[i].weight;
total_money -= a;
}
else
{
total_weight += total_money / rice[i].price;
break;
}
}
cout<<fixed<<setprecision(2);
cout<<total_weight<<endl;
}
return 0;
}

1.3.6 排序2  这一题,我学会了使用全排序方法,在格式上也花了点功夫才通过的

#include<string>
#include<iostream>
#include <iomanip>
#include<algorithm>
using namespace std;
/**
输入:
四个数字
输出:
由小到大输出组合四位数
*/
int main()
{
int num[1000][4], row = 0;
int a[4];
while(cin>>a[0]>>a[1]>>a[2]>>a[3])
{
if(a[0] == a[1] && a[1] == a[2] && a[2] == a[3] && a[3] == 0)
{
break;
}
//排序
sort(a, a+4);
for(int i = 0; i < 4; i++)
{
num[row][i] = a[i];
}
row++;
}

for(int k = 0; k < row; k++)
{
int i = 0, temp, temp_num = 0;
do
{
if(num[k][0] == 0)
{
continue;
}
if(i == 0)
{
temp = num[k][0];
}
else
{
if(num[k][0] == temp)
{
cout<<temp_num<<" ";
}
else
{
temp = num[k][0];
cout<<temp_num<<endl;
}
}
temp_num = num[k][0] * 1000 + num[k][1] * 100 + num[k][2] * 10 + num[k][3];
i += 1;
}
while(next_permutation(num[k],num[k]+4));
if(k != row - 1)
{
cout<<temp_num<<endl<<endl;
}
else
{
cout<<temp_num<<endl;
}
}
return 0;
}

1.3.7 rank  这个比较简单,一气呵成

#include<iostream>
#include<algorithm>
using namespace std;
/**
输入:
Jackson的学号(一个整数)
每个学生的学号 成绩
注:学生个数不超过1000
输出:
第几名
*/
struct student
{
int number; //学号
int mark; //成绩
};
bool compare(student std1, student std2)
{
return std1.mark > std2.mark; //降序
}
int main()
{
int number2, mark2, number, mark, count, i;
while(cin>>number2 && number2 != 0)
{
struct student std[1000];
count = 0;
while(cin>>number>>mark && number != 0 && mark != 0)
{
std[count].number = number;
std[count].mark = mark;
count++;
if(number2 == number)
{
mark2 = mark;
}
}
// 排序
sort(std, std+count,compare);
for(i = 0; i < count; i++)
{
if(mark2 == std[i].mark)
{
break;
}
}
i++;
cout<<i<<endl;
}
return 0;
}

1.3.8 Crixalis's Equipment   这种题目就是在排序算法上下功夫,要想好究竟按什么顺序排才合适

#include<iostream>
#include<algorithm>
using namespace std;
/**
输入:
案例个数
体积 设备的个数
各个设备所占体积 拖进洞至少要有的体积
输出:
Yes 或者 No
*/
struct equipment
{
int volumn; // 体积
int remain; // 拖进洞至少要有的体积
};
bool compare(equipment e1, equipment e2)
{
// 微妙的比较算法
return e1.volumn + e2.remain < e2.volumn + e1.remain;
}
int main()
{
int cases;
cin>>cases;
while(cases--)
{
int hole, count, volumn, remain;
cin>>hole>>count;
struct equipment equi[1000];
for(int i = 0; i < count; i++)
{
cin>>volumn>>remain;
equi[i].volumn = volumn;
equi[i].remain = remain;
}
// 排序
sort(equi, equi+count, compare);
int flag = 1;
for(int i = 0; i < count; i ++)
{
if(hole >= equi[i].remain)
{
if(hole >= equi[i].volumn)
{
hole -= equi[i].volumn;
}
else
{
flag = 0;
break;
}
}
else
{
flag = 0;
break;
}
}
if(flag)
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
}
return 0;
}

展示一下这两天的成果

ACM练习题C++版答案记录-Section 3_ACM

举报

相关推荐

0 条评论