您的位置:首页 > 编程语言 > C语言/C++

<C/C++算法>九度OJ题目1415--1464解题练习(八)

2015-01-25 14:13 561 查看


题目1415:不一样的循环队列

题目描述:

大家都知道数据结构里面有一个结构叫做循环队列。顾名思义,这是一个队列,并且是循环的。但是现在,淘气的囧哥给这个循环队列加上了一些规矩,其中有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


题目1419:文献排序

题目描述:
现在你的导师给你了一个待排序的参考文献列表,要你排好序给他。

文献列表中每一条文献记录只占一行。排序的规则和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;
}


题目1420:Jobdu MM分水果

题目描述:
Jobdu团队有俩PPMM,这俩MM干啥都想一样。一天,富强公司给团队赞助了一批水果,胡老板就把水果派发给了这俩MM,由她们自行分配。每个水果都有一个重量,你能告诉她们怎么分才使得分得的重量差值最小吗?

输入:
        输入有多组数据,每组数据第一行输入水果个数n(1<=n<=100),接下来一行输入n个重量wi(0<=wi<=10^5)。

输出:
对每组输入输出一行,输出可以得到的最小差值。

样例输入:
510 20 30 10 10

样例输出:
0


参考资源:http://blog.csdn.net/jdplus/article/details/21279141

#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
****************************************************************/



题目1434:今年暑假不AC

题目描述:

“今年暑假不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
****************************************************************/



题目1438:最小公倍数

题目描述:

给定两个正整数,计算这两个数的最小公倍数。
输入:

输入包含多组测试数据,每组只有一行,包括两个不大于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
****************************************************************/


题目1458:汉诺塔III

题目描述:

约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
****************************************************************/



题目1462:两船载物问题

时间限制:1 秒

内存限制:128 兆

特殊判题:否

提交:983

解决:285

题目描述:

给定n个物品的重量和两艘载重量分别为c1和c2的船,问能否用这两艘船装下所有的物品。

输入:

输入包含多组测试数据,每组测试数据由若干行数据组成。

第一行为三个整数,n c1 c2,(1 <= n <= 100),(1<=c1,c2<=5000)。

接下去n行,每行一个整数,代表每个物品的重量(重量大小不大于100)。

输出:

对于每组测试数据,若只使用这两艘船可以装下所有的物品,输出YES。

否则输出NO。

样例输入:
3 5 8
6
3
3
3 5 8
5
3
4


样例输出:
NO
YES


#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
****************************************************************/


题目1463:招聘会

题目描述:

又到毕业季,很多大公司来学校招聘,招聘会分散在不同时间段,小明想知道自己最多能完整的参加多少个招聘会(参加一个招聘会的时候不能中断或离开)。
输入:

第一行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
****************************************************************/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息