大家都知道数据结构里面有一个结构叫做循环队列。顾名思义,这是一个队列,并且是循环的。但是现在,淘气的囧哥给这个循环队列加上了一些规矩,其中有5条指令:
(1) Push K, 让元素K进队列。
(2) Pop,对头元素出队列。
(3) Query K,查找队列中第K个元素,注意K的合法性。
(4) Isempty,判断队列是否为空。
(5) Isfull,判断队列是否已满。
现在有N行指令,并且告诉你队列大小是M。
第一行包含两个整数N和M。1<=N,M<=100000。
接下来有N行,表示指令,指令格式见题目描述。
其中元素均在int范围。
对于指令(1),若队列已满,输出failed,否则不做输出。
对于指令(2),若队列已空,输出failed,否则不做输出。
对于指令(3),输出队列中第K个元素,若不存在,输出failed。
对于指令(4)和(5),则用yes或者no回答。
详情见样例。
12 2Push 1Push 2Push 3Query 2Query 3IsemptyIsfullPopPopPopIsemptyIsfull
failed2failednoyesfailedyesno
现在你的导师给你了一个待排序的参考文献列表,要你排好序给他。
文献列表中每一条文献记录只占一行。排序的规则和string类型字符串的比较规则一致(在排序时如果该字符串中包含大写字母,则当作小写字母处理,保证没有相同大小的字符串,但是输出结果不能改变任一字符串),按升序排列。
输入包括多组,每组输入第一行包括一个整数n,(1<=n<=200),接下来有n行,每行包括一行文献记录,文献记录的长度s(1<=s<=200)。
对每组输入。输出排好序的文献记录。
3abc hello!Abc hellz!bbc hello!
abc hello!Abc hellz!bbc hello!
#include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> #include <set> using namespace std; class NodeStr { public: string Literature; bool operator < (NodeStr modenode)//注意返回值的类型,运算符重载。 { string tmpliter1 = modenode.Literature; string tmpliter2 = Literature; for (int i = 0; i < tmpliter1.size(); i++) { if (tmpliter1[i] >= 65 && tmpliter1[i] <= 90) tmpliter1[i] = tmpliter1[i] + 32; } for (int i = 0; i < tmpliter2.size(); i++) { if (tmpliter2[i] >= 65 && tmpliter2[i] <= 90) tmpliter2[i] = tmpliter2[i] + 32; } return tmpliter2 < tmpliter1; } }; NodeStr nodestr[100]; int main() { int n = 0; while (cin>>n) { for (int i = 0; i < n; i++) cin >> nodestr[i].Literature; sort(nodestr, nodestr + n); for (int i = 0; i < n; i++) cout << nodestr[i].Literature << endl; } return 0; }
Jobdu团队有俩PPMM,这俩MM干啥都想一样。一天,富强公司给团队赞助了一批水果,胡老板就把水果派发给了这俩MM,由她们自行分配。每个水果都有一个重量,你能告诉她们怎么分才使得分得的重量差值最小吗?
输入有多组数据,每组数据第一行输入水果个数n(1<=n<=100),接下来一行输入n个重量wi(0<=wi<=10^5)。
对每组输入输出一行,输出可以得到的最小差值。
510 20 30 10 10
0
#include "vector" #include <cstdio> #include <iostream> #include "algorithm" #include<cstring> #include<cmath> #include<cstdlib> using namespace std; //将问题转化为动态规划: //假设所有水果总重为sum, 为了两个人分得尽可能相等(差值最小), //那么其中一个人所能分得的水果重量w范围一定在 (0,sum/2]之间, //问题就转化为一个人所分得的重量w尽可能接近sum/2。 //令dp[i]表示期望接近的重量值为i时,只对前j个物品进行选择最接近i的值 //(选择出来的重量和不超过i值,但是最接近) //每一个物品,我们可以选择,也可以不选 ,对物品的选择从一个到所有 //自底向上遍历求解,当期望接近的重量为i,在选择第j个物品时 //如果选择第j个物品,显然就是当前物品的价值fruit[j]加上最接近i - fruit[j]的值(即dp[i - fruit[j]]) //就是最接近i的值了,即dp[i] = dp[i - fruit[j]] + fruit[j](i应该递减) //如果不选,那就没变化,dp[i] = dp[i] (背包问题里面此时就是f[i][v]=f[i-1][v]) //谁更大,显然就更接近i值 int sum; int getMinDiff(vector<int> &fruit) { int i, j; int half = (sum >> 1); vector<int> dp(half+1,0); for (i = 0; i < fruit.size(); ++i)//水果的选择 { for (j = half; j >= fruit[i]; --j)//计算最接近j重量的值(在选择前i个物品时) { dp[j] = max(dp[j], dp[j - fruit[i]] + fruit[i]); } } return sum - 2 * dp[half]; } int main(int argc, char *argv[]) { int n = 0; while (scanf("%d", &n) != EOF) { sum = 0; vector<int> vecfruit(n, 0); for (int i = 0; i < n; ++i) { scanf("%d", &vecfruit[i]); sum += vecfruit[i]; } printf("%d\n", getMinDiff(vecfruit)); } return 0; } /************************************************************** Problem: 1420 User: EbowTang Language: C++ Result: Accepted Time:1110 ms Memory:4248 kb ****************************************************************/
“今年暑假不AC?”“是的。”“那你干什么呢?”“看世界杯呀,笨蛋!”“@#$%^&*%...”确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)
输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。
12 1 3 3 4 0 7 3 8 15 19 15 20 10 15 8 18 6 12 5 10 4 14 2 9 0
5
#include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> using namespace std; int GreedyActSelector(vector<int> &s, vector<int> &f); int main() { int n = 0; while (cin >> n&&n <= 1000) { if (n == 0) break; vector<int> vecstart(n); vector<int> vecend(n); //接受开始时间和结束时间 for (int i = 0; i < n; i++) cin >> vecstart[i] >> vecend[i]; //对其排序,要保证结束时间是有序的, for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (vecend[i]>vecend[j])//对结束时间排序,由小到大 { int temp1 = vecend[i]; vecend[i] = vecend[j]; vecend[j] = temp1; int temp2 = vecstart[i];//开始时间也相应变换,但不一定有序 vecstart[i] = vecstart[j]; vecstart[j] = temp2; } } } cout << GreedyActSelector(vecstart, vecend) << endl; } return 0; } //以第一个节目作为起点(为了能保证他是最早的对其排序。所以因为他是最早结束的,这样才可以尽可能增加多次活动的“潜力”), //总是选择满足兼容条件下的最早结束的节目,因为这样可以使得剩下的时间资源看其他节目, //这种选择方式一定可以选出最大的兼容节目数量。 int GreedyActSelector(vector<int> &start, vector<int> &finish) { int longlen = 0; int k = 0;//记录最近加入的节目的下标 int count = 1; for (int m = 1; m < start.size(); m++) {//start[m]是下一个节目的开始时间,finish[k]是上一个节目的结速时间, //我们总贪婪的找到下一个节目的开始时间比上一个的结束时间大 if (start[m] >= finish[k]) { count++; k = m; } } return count; } /************************************************************** Problem: 1434 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
给定两个正整数,计算这两个数的最小公倍数。
输入包含多组测试数据,每组只有一行,包括两个不大于1000的正整数。
对于每个测试用例,给出这两个数的最小公倍数,每个实例输出一行。
10 14
70
#include <iostream> using namespace std; int main() { int a, b; while (cin >> a >> b && a >= 1 && a <= 1000 && b >= 1 && b <= 1000) { int minGcd = 0; if (a>b) minGcd = a; else minGcd = b; while (minGcd%a != 0 || minGcd%b != 0) minGcd++; cout << minGcd << endl; } return 0; } /************************************************************** Problem: 1438 User: EbowTang Language: C++ Result: Accepted Time:120 ms Memory:1520 kb ****************************************************************/
约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。现在我们改变游戏的玩法,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面。Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在请你帮助她。现在有N个圆盘,她至少多少次移动才能把这些圆盘从最左边移到最右边?
包含多组数据,每次输入一个N值(1<=N=35)。
对于每组数据,输出移动最小的次数。
1 3 12
2 26 531440
#include <iostream> #include "stack" #include <cmath> #include <set> using namespace std; long long F(int num) { if (num == 1) return 2; else return 3 * F(num - 1) + 2; } int main() { int n; while (cin>>n) cout << F(n) << endl; return 0; } /************************************************************** Problem: 1458 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
#include "vector" #include <iostream> #include "algorithm" #include <stdio.h> #include <string.h> using namespace std; //将问题转化为动态规划: //假设所有物品总重为sum, 为了两个船装的下,必须sum<c1+c2, //那么其中载物重量较小的那艘船(令其为c1)尽可能装接近其载物量c1的物品总量和 //问题就转化为选择所有物品尽可能接近c1 (意义就是小船尽可能多装,为什么选择小船?内存消耗较小) //令dp[i]表示期望接近的重量值为i时,只对前j个物品进行选择时最接近i的值 //选择出来的重量和不超过i值,但是是基于前j个物品最接近 //每一个物品,我们可以选择,也可以不选 ,对物品的选择从一个到所有 //自底向上遍历求解,当期望接近的重量为i,在选择第j个物品时 //如果选择第j个物品,显然就是当前物品的重量weightlist[j]加上最接近i - weightlist[j]的值(即dp[i - weightlist[j]]) //就是最接近i的值了,即dp[i] = dp[i - weightlist[j]] + weightlist[j](i应该递减) //如果不选,那就没变化,dp[i] = dp[i] (背包问题里面此时就是f[i][v]=f[i-1][v]) //最后小船已经装载了dp[c1],那么如果大船只要再装sum-dp[c1],所以大船的载重量c2必须大于这个差值 int main() { int c1, c2, sum, n; while (~scanf("%d %d %d", &n, &c1, &c2)) { sum = 0; vector<int> weightlist(n + 1, 0); //接受输入 for (int i = 1; i <= n; i++) { scanf("%d", &weightlist[i]); sum += weightlist[i]; } if (c1 + c2<sum) { //物品的总重量大于两首船的载重 puts("NO"); continue; } //总是让c1成为较小者为了,总是先装载物较小的船 if (c1>c2) { int tmp = c1; c1 = c2; c2 = tmp; } vector<int> dp(c1+1, 0); for (int i = 1; i <= n; i++) for (int j = c1; j >= weightlist[i]; j--) dp[j] = max(dp[j - weightlist[i]] + weightlist[i], dp[j]); if (c2 + dp[c1]<sum) puts("NO"); else puts("YES"); } return 0; } /************************************************************** Problem: 1462 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
又到毕业季,很多大公司来学校招聘,招聘会分散在不同时间段,小明想知道自己最多能完整的参加多少个招聘会(参加一个招聘会的时候不能中断或离开)。
第一行n,有n个招聘会,接下来n行每行两个整数表示起止时间,由从招聘会第一天0点开始的小时数表示。
n <= 1000 。
最多参加的招聘会个数。
3 9 10 10 20 8 15
2
#include <iomanip>//小数点精确 #include "vector" #include "string" #include "algorithm" #include <iostream> #include <cstdio> using namespace std; int GreedyActSelector(vector<int> &s, vector<int> &f); int main() { int n = 0; while (cin >> n&&n <= 1000) { vector<int> vecstart(n); vector<int> vecend(n); for (int i = 0; i < n; i++) cin >> vecstart[i] >> vecend[i]; for (int i = 0; i < n; i++) { for (int j = i+1; j < n; j++) { if (vecend[i]>vecend[j])//对结束时间排序,由小到大 { int temp1 = vecend[i]; vecend[i] = vecend[j]; vecend[j] = temp1; int temp2 = vecstart[i];//开始时间也相应变换,但不一定有序 vecstart[i] = vecstart[j]; vecstart[j] = temp2; } } } cout << GreedyActSelector(vecstart, vecend) << endl; } return 0; } //以第一个招聘会作为起点(因为他是最早结束的,这样才可以尽可能增加多次活动的“潜力”), //总是选择满足兼容条件下的最早结束的活动,因为这样可以使得剩下的时间资源可以更多的其他活动使用, //这种选择方式一定可以选出最大兼容活动数。 int GreedyActSelector(vector<int> &start, vector<int> &finish) { int longlen = 0; int k = 0;//记录最近加入的活动的下标 int count = 1; for (int m = 1; m < start.size(); m++) { if (start[m] >= finish[k])//start[m]是下一个活动的开始时间,finish[k]是上一个活动的结速时间,我们总贪婪的找到下一个活动的开始时间比上一个的结束时间大 { count++; k = m; } } return count; } /************************************************************** Problem: 1463 User: EbowTang Language: C++ Result: Accepted Time:20 ms Memory:1520 kb ****************************************************************/