[Coursera C++程序设计] 第九周作业

编程题#1

来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述

下面的程序用枚举法解决如下问题,请填空。

平面上的一个矩形,如果其边平行于坐标轴,我们就称其为“标准矩形”。给定不重复的 n 个整点(横、纵坐标都是整数的点),求从这n个点中任取4点作为顶点所构成的四边形中,有多少个是标准矩形。

 

1

2

3

4

5

6

扫描二维码关注公众号,回复: 2410912 查看本文章

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

struct Point {

int x;

int y;

Point(int x_,int y_):x(x_),y(y_) { }

};

bool operator < ( const Point & p1, const Point & p2)

{

if( p1.y < p2.y )

return true;

else if( p1.y == p2.y )

return p1.x < p2.x;

else

return false;

}

int main()

{

int t;

int x,y;

cin >> t;

vector<Point> v;

while( t -- ) {

cin >> x >> y;

v.push_back(Point(x,y));

}

vector<Point>::iterator i,j;

int nTotalNum = 0;

// 在此处补充你的代码

return 0;

}

 

输入

第一行是点的数目

其后每一行都代表一个点,由两个整数表示,第一个是x坐标,第二个是y坐标

 

输出

输出标准矩形的数目

样例输入

 

1

2

3

4

5

6

7

6

2 3

2 5

4 5

4 4

2 4

4 3

 

样例输出

 

1

3

 

提示

所缺代码具有如下形式:

 

1

2

3

4

5

6

7

8

9

10

_____________________;

for( i = v.begin(); i < v.end() - 1;i ++ )

for(_____________; ______________; _____________) {

if(binary_search(v.begin(),v.end(),Point( j->x, i->y)) &&

____________________________________________ &&

____________________________________________ &&

____________________________________________ )

nTotalNum ++;

}

cout << _________________;

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Point {
    int x;
    int y;
    Point(int x_,int y_):x(x_),y(y_) { }
};
bool operator < ( const Point & p1, const Point & p2)
{
    if( p1.y < p2.y )
        return true;
    else if( p1.y == p2.y )
        return p1.x < p2.x;
    else
        return false;
}
int main()
{
    int t;
    int x,y;
    cin >> t;
    vector<Point> v;
    while( t -- ) {
        cin >> x >> y;
        v.push_back(Point(x,y));
    }
    vector<Point>::iterator i,j;
    int nTotalNum = 0;
// 在此处补充你的代码
    sort(v.begin(),v.end());
    for( i = v.begin(); i < v.end() - 1;i ++ )
        for(j = i+1; j < v.end(); j++) {
            if(binary_search(v.begin(),v.end(),Point( j->x, i->y)) &&
               binary_search(v.begin(),v.end(),Point(i->x, j->y)) &&
               i ->x != j->x &&
               i->y != j->y )
                nTotalNum ++;
        }
    cout << nTotalNum / 2;
    return 0;
}

编程题#2

来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)

注意: 总时间限制: 1000ms 内存限制: 65536kB

 

描述

写一个自己的 CMyistream_iterator 模板,使之能和 istream_iterator 模板达到一样的效果,即:

输入:

79 90 20 hello me

输出:

79

79,90,20

hello,me

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#include <iostream>

#include <string>

using namespace std;

// 在此处补充你的代码

int main()

{

CMyistream_iterator<int> inputInt(cin);

int n1,n2,n3;

n1 = * inputInt; //读入 n1

int tmp = * inputInt;

cout << tmp << endl;

inputInt ++;

n2 = * inputInt; //读入 n2

inputInt ++;

n3 = * inputInt; //读入 n3

cout << n1 << "," << n2<< "," << n3 << endl;

CMyistream_iterator<string> inputStr(cin);

string s1,s2;

s1 = * inputStr;

inputStr ++;

s2 = * inputStr;

cout << s1 << "," << s2 << endl;

return 0;

}

 

输入

79 90 20 hello me

 

输出

79

79,90,20

hello,me

 

样例输入

 

1

79 90 20 hello me

 

样例输出

 

1

2

3

79

79,90,20

hello,me

 

提示

istream_iterator模版使用说明:

其构造函数执行过程中就会要求输入,然后每次执行++,则读取输入流中的下一个项目,执行 * 则返回上次从输入流中读取的项目。例如,下面程序运行时,就会等待用户输入数据,输入数据后程序才会结束:

 

1

2

3

4

5

6

7

#include <iostream>

#include <iterator>

using namespace std;

int main() {

istream_iterator<int> inputInt(cin);

return 0;

}

下面程序运行时,如果输入 12 34 程序输出结果是: 12,12

 

1

2

3

4

5

6

7

8

9

#include <iostream>

#include <iterator>

using namespace std;

int main()

{

istream_iterator<int> inputInt(cin);

cout << * inputInt << "," << * inputInt << endl;

return 0;

}

下面程序运行时,如果输入 12 34 56程序输出结果是: 12,56

 

1

2

3

4

5

6

7

8

9

10

11

12

#include <iostream>

#include <iterator>

using namespace std;

int main()

{

istream_iterator<int> inputInt(cin);

cout << * inputInt << "," ;

inputInt ++;

inputInt ++;

cout << * inputInt;

return 0;

}

#include <iostream>
#include <string>
using namespace std;
// 在此处补充你的代码
template <class T>
class CMyistream_iterator
{
public:
    CMyistream_iterator(istream &input):is(input) {
        is>>a;
    }
    T operator *() {
        return a;
    }
    void operator ++(int) {
        is>>a;
    }
private:
    T a;
    istream & is;
};
int main()
{
    CMyistream_iterator<int> inputInt(cin);
    int n1,n2,n3;
    n1 = * inputInt; //读入 n1
    int tmp = * inputInt;
    cout << tmp << endl;
    inputInt ++;
    n2 = * inputInt; //读入 n2
    inputInt ++;
    n3 = * inputInt; //读入 n3
    cout << n1 << "," << n2<< "," << n3 << endl;
    CMyistream_iterator<string> inputStr(cin);
    string s1,s2;
    s1 = * inputStr;
    inputStr ++;
    s2 = * inputStr;
    cout << s1 << "," << s2 << endl;
    return 0;
}

编程题#3:Set

来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)

注意: 总时间限制: 5000ms 内存限制: 100000kB

描述

现有一整数集(允许有重复元素),初始为空。我们定义如下操作:

add x 把x加入集合

del x 把集合中所有与x相等的元素删除

ask x 对集合中元素x的情况询问

对每种操作,我们要求进行如下输出。

add 输出操作后集合中x的个数

del 输出操作前集合中x的个数

ask 先输出0或1表示x是否曾被加入集合(0表示不曾加入),再输出当前集合中x的个数,中间用空格格开。

 

输入

第一行是一个整数n,表示命令数。0<=n<=100000。

后面n行命令,如Description中所述。

 

输出

共n行,每行按要求输出。

 

样例输入

 

1

2

3

4

5

6

7

8

7

add 1

add 1

ask 1

ask 2

del 2

del 1

ask 1

 

样例输出

 

1

2

3

4

5

6

7

1

2

1 2

0 0

0

2

1 0

 

提示

Please use STL’s set and multiset to finish the task


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

int main()
{
	multiset<int> m1;
	set<int> m2;
	int n;
	cin >> n;
	cin.get();//吃回车
	string tmp;
	while (cin >> tmp) {
		int m = 0;
		if (tmp == "add") {
			cin >> m;
			m1.insert(m);
			m2.insert(m);
			cout << m1.count(m) << endl;
		}
		if (tmp == "ask") {
			cin >> m;
			if (m2.find(m) == m2.end())
				cout << "0 0" << endl;
			else
				cout << "1 " << m1.count(m) << endl;
		}
		if (tmp == "del") {
			cin >> m;
			cout << m1.count(m) << endl;
			m1.erase(m);
		}
	
	}
	return 0;
}

编程题#4: 字符串操作

来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述

给定n个字符串(从1开始编号),每个字符串中的字符位置从0开始编号,长度为1-500,现有如下若干操作:

copy N X L:取出第N个字符串第X个字符开始的长度为L的字符串。

add S1 S2:判断S1,S2是否为0-99999之间的整数,若是则将其转化为整数做加法,若不是,则作字符串加法,返回的值为一字符串。

find S N:在第N个字符串中从左开始找寻S字符串,返回其第一次出现的位置,若没有找到,返回字符串的长度。

rfind S N:在第N个字符串中从右开始找寻S字符串,返回其第一次出现的位置,若没有找到,返回字符串的长度。

insert S N X:在第N个字符串的第X个字符位置中插入S字符串。

reset S N:将第N个字符串变为S。

print N:打印输出第N个字符串。

printall:打印输出所有字符串。

over:结束操作。

其中N,X,L可由find与rfind操作表达式构成,S,S1,S2可由copy与add操作表达式构成。

 

输入

第一行为一个整数n(n在1-20之间)

接下来n行为n个字符串,字符串不包含空格及操作命令等。

接下来若干行为一系列操作,直到over结束。

 

输出

根据操作提示输出对应字符串。

 

样例输入

 

1

2

3

4

5

6

7

8

9

10

11

3

329strjvc

Opadfk48

Ifjoqwoqejr

insert copy 1 find 2 1 2 2 2

print 2

reset add copy 1 find 3 1 3 copy 2 find 2 2 2 3

print 3

insert a 3 2

printall

over

 

样例输出

 

1

2

3

4

5

Op29adfk48

358

329strjvc

Op29adfk48

35a8

 

提示

推荐使用string类中的相关操作函数。

#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <cstdlib>//atoi字符串转整数的函数
#include <cstring>//memset函数头文件
#include <cstdio>//sprintf函数头文件
using namespace std;

vector<string> strGiven;//存储被给的字符串
queue<string> strCommand;//存储命令字符串
char* strItoa = new char[101];//存储将整数转换的字符串,并作返回值使用

void strStorage(const char* ch);//将输入的一行数据分为若干个命令参数,并存入队列当中
bool strProcess();//开始处理一行命令,注意开头的命令只可能是“insert”“reset”“print”“printall”和“over”
string commandOp();//递归算法处理一行中的命令组合
string nyCopy(int n, int x, int l);//copy N X L:取出第N个字符串第X个字符开始的长度为L的字符串
string nyAdd(string s1, string s2);//add S1 S2:判断S1,S2是否为0-99999之间的整数,若是则将其转化为整数做加法,若不是,则作字符串加法,返回的值为一字符串
int nyFind(int n, string s);//find S N:在第N个字符串中从左开始找寻S字符串,返回其第一次出现的位置,若没有找到,返回字符串的长度。
int nyRFind(int n, string s);//rfind S N:在第N个字符串中从右开始找寻S字符串,返回其第一次出现的位置,若没有找到,返回字符串的长度。
void nyInsert(int n, int x, string s);//在第N个字符串的第X个字符位置中插入S字符串
void nyReset(int n, string s);//将第N个字符串变为S
void nyPrint(int n);//打印输出第N个字符串
void nyPrintAll();//打印输出所有字符串

int main()
{
	int n;
	cin >> n;

	for (int i = 0; i < n; i++)
	{
		string str;
		cin >> str;
		strGiven.push_back(str);
	}
	cin.get();

	char* ch = new char[501];
	while (1)
	{
		cin.getline(ch, 500, '\n');
		strStorage(ch);
		int t = strProcess();
		if (t == false)
		{
			break;
		}
	}
	delete ch;
	delete strItoa;
	return 0;
}
/*
将输入的一行数据分为若干个命令参数,并存入队列当中
*/
void strStorage(const char* ch)
{
	string str;
	for (int i = 0; ch[i] != '\0'; i++)
	{
		if (ch[i] != ' ')
		{
			str.push_back(ch[i]);
		}
		else
		{
			strCommand.push(str);
			str.clear();
		}
	}
	//记录最后一个字符串
	strCommand.push(str);
}
/*
开始处理一行命令,注意开头的命令只可能是“insert”“reset”“print”“printall”和“over”
遇到"over"时返回false,程序结束
*/
bool strProcess()
{
	string str = strCommand.front();
	strCommand.pop();
	if (str == "insert")
	{
		string s = commandOp();
		int n = atoi(commandOp().c_str());
		int x = atoi(commandOp().c_str());
		nyInsert(n, x, s);
	}
	else if (str == "reset")
	{
		string s = commandOp();
		int n = atoi(commandOp().c_str());
		nyReset(n, s);
	}
	else if (str == "print")
	{
		int n = atoi(commandOp().c_str());
		nyPrint(n);
	}
	else if (str == "printall")
	{
		nyPrintAll();
	}
	else if (str == "over")
	{
		return false;
	}
	return true;
}
/*
递归算法处理一行中的命令组合
*/
string commandOp()
{
	string str = strCommand.front();
	strCommand.pop();
	if (str == "copy")
	{
		int n = atoi(commandOp().c_str());
		int x = atoi(commandOp().c_str());
		int l = atoi(commandOp().c_str());
		return nyCopy(n, x, l);
	}
	else if (str == "add")
	{
		string s1 = commandOp();
		string s2 = commandOp();
		return nyAdd(s1, s2);
	}
	else if (str == "find")
	{
		string s = commandOp();
		int n = atoi(commandOp().c_str());
		sprintf(strItoa, "%d", nyFind(n, s));
		return strItoa;
	}
	else if (str == "rfind")
	{
		string s = commandOp();
		int n = atoi(commandOp().c_str());
		sprintf(strItoa, "%d", nyRFind(n, s));
		return strItoa;
	}
	else//参数
	{
		return str;
	}

}
/*
copy函数
*/
string nyCopy(int n, int x, int l)
{
	string str = strGiven.at(n - 1);
	return str.substr(x, l);
}
/*
add函数
*/
string nyAdd(string s1, string s2)
{
	//判断字符串里是否全为数字
	//因为83s经过atoi后会变为83
	for (int i = 0; i < s1.size(); i++)
	{
		if (s1.at(i) < '0' || s1.at(i) > '9')
		{
			return s1 + s2;
		}
	}
	for (int i = 0; i < s2.size(); i++)
	{
		if (s2.at(i) < '0' || s2.at(i) > '9')
		{
			return s1 + s2;
		}
	}
	//若全为数字,判断是否在0和99999之间
	long a = atoi(s1.c_str());
	long b = atoi(s2.c_str());
	if (a >= 0 && a <= 99999 && b >= 0 && b <= 99999)
	{
		long c = a + b;
		sprintf(strItoa, "%d", c);
		return strItoa;
	}
	else
	{
		return s1 + s2;
	}
}
/*
find函数
*/
int nyFind(int n, string s)
{
	int pos = strGiven.at(n - 1).find(s);
	if (pos == string::npos)
	{
		return s.size();
	}
	else
	{
		return pos;
	}
}
/*
rfind函数
*/
int nyRFind(int n, string s)
{
	int pos = strGiven.at(n - 1).rfind(s);
	if (pos == string::npos)
	{
		return s.size();
	}
	else
	{
		return pos;
	}
}
/*
insert函数
*/
void nyInsert(int n, int x, string s)
{
	strGiven.at(n - 1).insert(x, s);
}
/*
reset函数
*/
void nyReset(int n, string s)
{
	strGiven.at(n - 1).swap(s);
}
/*
print函数
*/
void nyPrint(int n)
{
	cout << strGiven.at(n - 1) << endl;
}
/*
printall函数
*/
void nyPrintAll()
{
	for (unsigned int i = 0; i < strGiven.size(); i++)
	{
		cout << strGiven.at(i) << endl;
	}

}

编程题#5: 热血格斗场

来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述

为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家热血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。

我们假设格斗的实力可以用一个正整数表示,成为实力值。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有两个人的实力值与他差别相同,则他会选择比他弱的那个(显然,虐人必被虐好)。

不幸的是,Facer一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮facer恢复比赛纪录,按照时间顺序依次输出每场比赛双方的id。

 

输入

第一行一个数n(0 < n <=100000),表示格斗场新来的会员数(不包括facer)。以后n行每一行两个数,按照入会的时间给出会员的id和实力值。一开始,facer就算是会员,id为1,实力值1000000000。输入保证两人的实力值不同。

 

输出

N行,每行两个数,为每场比赛双方的id,新手的id写在前面。

 

样例输入

 

1

2

3

4

3

2 1

3 3

4 2

 

样例输出

 

1

2

3

2 1

3 2

4 2

#include <iostream>
#include <map>
#include <cmath>
using namespace std;

typedef map<int, int> MAP;

int main()
{
	MAP::key_type strength;
	MAP::mapped_type id;
	MAP member;
	pair<MAP::iterator, bool> pairs;//创建pair模板类的对象

	member[1000000000] = 1;//插入数据
	int id1 = 0, id2 = 0, s1 = 0, s2 = 0;//记录实力左右与他最为接近的人
	id1 = 1;
	s1 = 1000000000;
	int n;
	cin >> n;
	while (n--)
	{
		cin >> id >> strength;//scanf("%d %d", &id, &strength);
		pairs = member.insert(MAP::value_type(strength, id));//插入数据并取得其迭代指针
		MAP::iterator i = pairs.first;

		if (i == member.begin())//如果其实力值最小
		{
			i++;
			cout << id << ' ' << i->second << endl;//printf("%d %d\n", id, i->second);
			continue;
		}
		else
		{
			i--;
			id1 = i->second;//得到比其实力小的邻居
			s1 = i->first;
			i++;

			i++;
			id2 = i->second;//得到比其实力小的邻居
			s2 = i->first;

			if (abs(s2 - strength) == abs(s1 - strength))
			{
				if (s1 < s2)
				{
					cout << id << ' ' << id1 << endl;
				}
				else
				{
					cout << id << ' ' << id2 << endl;
				}
			}
			else if ((abs(s1 - strength) < abs(s2 - strength)) || i == member.end())
			{
				cout << id << ' ' << id1 << endl;
			}
			else
			{
				cout << id << ' ' << id2 << endl;
			}
		}
	}
	return 0;
}

编程题#6: priority queue练习题

来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)

注意: 总时间限制: 2500ms 内存限制: 131072kB

描述

我们定义一个正整数a比正整数b优先的含义是:

*a的质因数数目(不包括自身)比b的质因数数目多;

*当两者质因数数目相等时,数值较大者优先级高。

现在给定一个容器,初始元素数目为0,之后每次往里面添加10个元素,每次添加之后,要求输出优先级最高与最低的元素,并把该两元素从容器中删除。

 

输入

第一行: num (添加元素次数,num <= 30)

下面10*num行,每行一个正整数n(n < 10000000).

 

输出

每次输入10个整数后,输出容器中优先级最高与最低的元素,两者用空格间隔。

 

样例输入

 

1

2

1

10 7 66 4 5 30 91 100 8 9

 

样例输出

 

1

66 5

#include<queue>
#include<iostream>
#include <bitset>
using namespace std;

bitset<3200> tab;

int getNum(int k) {
	int num = 0;
	for (int j = 2; j < 3200 && j < k; j++) {
		if (tab[j] == 0 && k % j == 0) {
			while (k % j == 0)
				k /= j;
			num++;
			if (k == 1) break;
		}
	}
	if (k == 1)
		return num;
	else if (num == 0)
		return 0;
	else
		return num + 1;
}


class MyLess {
public:
	bool operator() (pair<int, int> a, pair<int, int> b) {
		int num1 = a.first, num2 = a.first;
		if (num1 < num2)
			return true;
		else if (num1 == num2)
			return a < b;
		else
			return false;
	}
};

class MyGreater {
public:
	bool operator() (pair<int, int> a, pair<int, int> b) {
		int num1 = a.first, num2 = a.first;
		if (num1 > num2)
			return true;
		else if (num1 == num2)
			return a > b;
		else
			return false;
	}
};

int main() {
	for (int i = 0; i < 3200; i++)
		tab[i] = 0;
	tab[0] = tab[1] = 1;
	for (int i = 2; i < 3200; i++) {
		if (!tab[i])
			for (int j = i + i; j < 3200; j += i)
				tab[j] = 1;
	}

	int num = 0;
	priority_queue<int, vector<pair<int, int> >, MyLess> pq1;
	priority_queue<int, vector<pair<int, int> >, MyGreater> pq2;
	
	int n;
	cin >> num;
	while (num--) {
		int tmp = 0;
		for (int t = 0; t < 10; t++) {
			cin >> tmp;
			pq1.push(make_pair(getNum(tmp), tmp));
			pq2.push(make_pair(getNum(tmp), tmp));
		}
		cout << pq1.top().second << " " << pq2.top().second << endl;
		pq1.pop();
		pq2.pop();
	}
	return 0;

}

猜你喜欢

转载自blog.csdn.net/qq_30945147/article/details/81222517