JobduInCPlusPlus
Solutions to Jobdu problems based on C++
Install / Use
/learn @zpfbuaa/JobduInCPlusPlusREADME
JobduInCPlusPlus
九度OJ永久关闭
- 详细见http://www.cskaoyan.com/thread-647811-1-1.html
List
- 题目1002:Grading(简单判断)
- 题目1003:A+B(带逗号的A+B)
- 题目1004:Median(qsort函数)
- 题目1005:Graduate Admission(录取算法)
- 题目1006:ZOJ问题(递推规律)
- 题目1007:奥运排序问题(自定义排序)
- 题目1008:最短路径问题(最短路径问题dijkstra算法)
- 题目1009:二叉搜索树(是否为同一个二叉搜索树)
- 题目1010:A + B(字符串转数字)
- 题目1011:最大连续子序列(标记边界)
- 题目1012:畅通工程(并查集以及路径优化)
- 题目1013:开门人和关门人(结构体使用qsort排序)
- 题目1014:排名(结构体使用自定义cmp排序规则)
- 题目1015:还是A+B(简单判断)
- 题目1016:火星A+B(进制转换新问题)
- 题目1017:还是畅通工程(最小生成树初步)
- 题目1018:统计同成绩学生人数(简单统计)
- 题目1019:简单计算器(栈的使用)
- 题目1020:最小长方形(排除原点)
- 题目1021:统计字符(字符统计)
- 题目1022:游船出租(结构体使用)
- 题目1024:畅通工程(最小生成树kruskal算法)
- 题目1025:最大报销额(0-1背包问题)
- 题目1028:继续畅通工程(最小生成树kruskal算法)
- 题目1029:魔咒词典(STLmap使用)
- 题目1035:找出直系亲属(计算树的深度)
- 题目1040:Prime Number(第k个素数)
- 题目1042:Coincidence(最长公共子序列dp题目)
- 题目1048:判断三角形类型(直角、钝角、锐角)
- 题目1049:字符串去特定字符(简单判断)
- 题目1061:成绩排序(自定义排序)
- 题目1076:N的阶乘(大数乘法)
- 题目1077:最大序列和(最大连续子序列和)
- 题目1078:二叉树遍历(二叉树操作)
- 题目1079:手机键盘(对应关系)
- 题目1080:进制转换(大整数任意进制转换)
- 题目1081:递推数列(矩阵二分乘法)
- 题目1082:代理服务器(贪心算法)
- 题目1083:特殊乘法(求模运算符使用)
- 题目1084:整数拆分(递推算法)
- 题目1085:求root(N, k)(二分求幂&进制转换)
- 题目1089:数字反转(简单判断)
- 题目1091:棋盘游戏(DFS)
- 题目1095:2的幂次方(递归函数)
- 题目1099:后缀子串排序(qsort自定义cmp函数)
- 题目1100:最短路径(最短路径进阶)
- 题目1101:计算表达式(栈的使用)
- 题目1102:最小面积子矩阵(暴力求解以及最大连续子序列)
- 题目1103:二次方程计算器(字符串操作&基础数学知识)
- 题目1104:整除问题(大数相乘,素数问题)
- 题目1111:单词替换(字符串查找)
- 题目1112:拦截导弹(最长非递增子序列)
- 题目1120:全排列(回溯法)
- 题目1131:合唱队形(最长递增子序列进阶题)
- 题目1137:浮点数加法(高精度浮点数加法)
- 题目1144:Freckles(最小生成树进阶)
- 题目1153:括号匹配问题(栈的使用)
- 题目1161:Repeater (规律输出)
- 题目1162:I Wanna Go Home(最短路径问题进阶)
- 题目1168:字符串的查找删除(字符串操作)
- 题目1198:a+b(高精度加法实现)
- 题目1208:10进制 VS 2进制(任意进制转换&大数保存)
- 题目1438:最小公倍数(利用最大公约数)
- 题目1439:Least Common Multiple(最小公倍数)
- 题目1440:Goldbach's Conjecture(哥德巴赫猜想)
- 题目1441:人见人爱 A ^ B(二分求幂)
- 题目1442:A sequence of numbers(数列计算)
- 题目1446:Head of a Gang(并查集操作)
- 题目1447:最短路(floyd算法)
- 题目1448:Legal or Not(有向无环图——拓扑排序问题)
- 题目1449:确定比赛名次(有向无环图&优先队列——拓扑排序问题进阶题)
- 题目1450:产生冠军(拓扑排序简单题)
- 题目1451:不容易系列之一(递推求解)
- 题目1452:搬寝室(dp题目)
- 题目1453:Greedy Tino(dp题目)
- 题目1454:Piggy-Bank(完全背包问题)
- 题目1455:珍惜现在,感恩生活(多重背包问题)
- 题目1456:胜利大逃亡(广度优先搜索BFS)
- 题目1457:非常可乐(广度优先搜素BFS)
- 题目1458:汉诺塔III(递归算法)
- 题目1459:Prime ring problem(素数环问题)
- 题目1460:Oil Deposit(回溯法)
- 题目1461:Tempter of the bone(深度优先遍历)
Detail
<font color = Green> <span id="1002">题目1002:Grading</span></font>
Jobdu Link:<br>
http://ac.jobdu.com/problem.php?pid=1002
Problem description:<br>
题目背景为高考试卷批改打分制度。对于每一道题,至少需要两位评审老师进行打分,当两个老师的打分结果相差在可接受范围内,那么该题最终得分为两位老师所给分数的平均分。<br> 当打分相差较大超过可接受范围时,需要第三位评审老师打分。<br> 如果第三位评审老师所给分数之和其中一位老师所给分数相差在可接受范围内,则最终分数为这两位老师所给分数的平均分。<br> 如果第三位老师所给分数和前面两位老师所给分数之差均为可接受范围内,则最终分数取三位老师所给分数的最高分。<br> 如果第三位老师所给分数和前面两位所给分数之差均超过可接受范围,则需要第四位评审老师给出分数,最终分数为第四位老师所给分数。
Source code:<br>
http://www.cnblogs.com/zpfbuaa/p/6711256.html
<font color = Blue size = 5> Analysis:</font>
原题目为英文,看懂题目就很简单了。注意使用类型为double。并要注意输出精确到小数点后一位,使用
printf("%.1lf\n",ans)
Back to list
<font color = Green> <span id="1003">题目1003:A+B</span></font>
Jobdu Link:<br>
http://ac.jobdu.com/problem.php?pid=1003
Problem description:<br>
给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号","隔开。<br> 现在请计算A+B的结果,并以正常形式输出。 输入要求:输入包含多组数据数据,每组数据占一行,由两个整数A和B组成(-10^9 < A,B < 10^9)。<br> 输出要求:请计算A+B的结果,并以正常形式输出,每组数据加换行。<br>
Source code:<br>
http://www.cnblogs.com/zpfbuaa/p/6711267.html
<font color = Blue size = 5> Analysis:</font>
两个整数带逗号,因此数据可使用char数组保存。之后需要将char数组保存的数据转为相对于的int类型的数字。转换方法有很多,下面给出一种:<br> 求出char数组中保存数据的长度len,然后设置一个保存最终转换结果的int型变量并且初始化为0.除此之外设置一个记录当前数字长度的变量,用于倒序读取char数组,不断更新最终结果。然后还需要一个变量进行对转换的数字标记是正数还是负数,可以使用bool变量. 核心代码见下:
<pre> int lena = (int)strlen(a); int size1 = 0; int num1 = 0; bool flag1 = (a[0]>='0'&&a[0]<='9') ? true : false;//默认0也是正数了! for(int i = lena -1 ; i >= 0 ; i--){ if(a[i]>='0' && a[i]<='9'){ num1+=(a[i]-'0')*pow(10,size1); size1++; } } </pre>通过上述转换,可以得到最后的结果,然后根据A和B的符号进行相应的加法和减法操作即可。
<pre> if(flag1&&flag2) printf("%d\n",num1+num2); else if(flag1 && !flag2) printf("%d\n",num1-num2); else if(flag2 && !flag1) printf("%d\n",num2-num1); else if(!flag1 && !flag2) printf("%d\n",0-num1-num2); </pre>
Back to list
<font color = Green> <span id="1004">题目1004:Median</span></font>
Jobdu Link:<br>
http://ac.jobdu.com/problem.php?pid=1004
Problem description:<br>
题目大致含义:给两个非递减的数组,找到两个数组的中位数。
输入要求:多组数据输入,第一行第一个数字为n,表示第一个数组有n个数字。第二行第二个数字为m,表示第二个数组有m个数字。<br>
输出要求:两个数组的中位数。
Source code:<br>
http://www.cnblogs.com/zpfbuaa/p/6832183.html
<font color = Blue size = 5> Analysis:</font>
使用一个足够大的数组保存下来全部的数字,进行排序之后求得中位数。<br>
<pre> int cmp(void const * a, void const * b){ return * (int * )a - * (int * )b; } qsort(a,n+m,sizeof(a[0]),cmp); </pre>
Back to list
<font color = Green> <span id="1005">题目1005:Graduate Admission</span></font>
Jobdu Link:<br>
http://ac.jobdu.com/problem.php?pid=1005
Problem description:<br>
题目大致意思:现在有n个学生填报志愿,一共有m个学校招生,每个学生的填报志愿个数为k个。其中n取值范围为[1,40000]。m取值范围为[1,100],k取值范围为[1,5]。每个学生的成绩由两部分组成,初试成绩为GE,复试成绩为GI,最终成绩GF为(GE+GI)/2。学生成绩排名规则如下所示:按照最终成绩排名,如果最终成绩相同,那么初试成绩GE越高排名越靠前;如果初试成绩也相同,那么排名相同。学校录取规则如下:每个学校有额定录取名额,一旦录取人数达到录取名额则不再录取,但是如果多个人的排名相同(GF相同并且GE也相同)那么无论超过录取名额多少都要录取。<br>
输入要求:多组数据,第一行为三个整数,n,m,k。分别代表学生个数,学校个数,志愿个数。接下来一行有m个正数,表示每个学校的额定录取人数。学校编号从0到m-1,编号为i的录取人数为第i个正数。接下来有n行,每一行有2+k个正数,第一个正数表示初试成绩GE,第二个整数表示复试成绩GI,接下来k个正数依次为填报志愿的顺序。<br>
输出要求:第i行为编号为i-1的学校的录取情况,输出学生的编号。学生的编号从0到n-1。如果当期学校没有录取任何学生则输出空行。<br>
Source code:<br>
http://www.cnblogs.com/zpfbuaa/p/6776372.html
<font color = Blue size = 5> Analysis:</font>
为了保存学生志愿信息,可以利用结构体。如下所示:
<pre> #define CHOOSE 6 #define MAX_SIZE 40001 #define SCHOOL 101 struct Apply{ int ge; int gi; double gf; int choose[CHOOSE]; int id; bool operator < (const Apply &A) const{ if(gf != A.gf){ return gf > A.gf; } else if(ge != A.ge){ return ge > A.ge; } else { return ge > A.ge; } } }; </pre>为了存储学校录取情况,定义如下结构体:<br>
<pre> struct School{ int quota; int realNum; int appid[MAX_SIZE]; }; </pre>接下来要先按照成绩规则进行排名,在结构体中一定重载了小于运算符,因此调用STL提供的sort函数即可。 在对成绩做好排序之后,需要进行学校的录取,一次按照成绩排名选择其填报的志愿,如果被学校录取则需要将学生id放入学校的录取名单中,并且该学校的录取名额减去1,实际录取名额加1。同属需要判断当前学校录取的最后一位同学与现在申请该学校的学生的排名是否相同,如果相同那么无论是否超过额定录取名额,都要录取该学生。<br>
<pre> sort(apply,apply+n); int sid; for(int i = 0 ; i < n ; i++){ for(int j = 0 ; j < k ; j++){ sid = apply[i].choose[j]; if(school[sid].quota > 0){ school[sid].appid[school[sid].realNum] = i; school[sid].realNum++; school[sid].quota--; break; } else{ int lastid = school[sid].appid[school[sid].realNum-1]; if(apply[i].gf == apply[lastid].gf && apply[i].ge == apply[lastid].ge){ school[sid].appid[school[sid].realNum]=i; school[sid].realNum++; school[sid].quota--; break; } } } } for(int i = 0 ; i < m ; i++){ for(int j = 0 ; j < school[i].realNum ; j++){ school[i].appid[j] = apply[school[i].appid[j]].id;//保存学生的id } } </pre>输出学校信息时,需要注意当前学校是否录取有学生:<br>
<pre> for(int i = 0 ; i < m ; i++){ if(school[i].realNum==0){ printf("\n"); } else if(school[i].realNum==1){ printf("%d\n",school[i].appid[0]); } else{ sort(school[i].appid,school[i].appid+school[i].realNum); bool first = true;//第一个学生前面没有前置空格 for(int j = 0 ; j < school[i].realNum ; j++){ if(first==true){ first = false; } else{ printf(" "); } printf("%d",school[i].appid[j]);//学校i的第j个录取的学生的id } printf("\n"); } } </pre>
