第九周编程作业
- A:list
- 总时间限制:
- 4000ms
- 内存限制:
- 65536kB
- 描写叙述
-
写一个程序完毕下面命令:
new id ——新建一个指定编号为id的序列(id<10000)
add id num——向编号为id的序列增加整数num
merge id1 id2——合并序列id1和id2中的数,并将id2清空
unique id——去掉序列id中反复的元素
out id ——从小到大输出编号为id的序列中的元素,以空格隔开 - 输入
- 第一行一个数n,表示有多少个命令( n<=200000)。以后n行每行一个命令。
- 输出
- 按题目要求输出。
- 例子输入
-
16 new 1 new 2 add 1 1 add 1 2 add 1 3 add 2 1 add 2 2 add 2 3 add 2 4 out 1 out 2 merge 1 2 out 1 out 2 unique 1 out 1
- 例子输出
-
1 2 3 1 2 3 4 1 1 2 2 3 3 4 1 2 3 4
#include <list> #include <iostream> #include <map> #include <fstream> using namespace std; typedef map< int, list<int> > Map; int main() { ifstream cin("D:\\Download\\in.txt"); int id1, id2, num, n; char str[10]; Map ml; list<int>::iterator i; cin >> n; while (n--) { cin >> str; switch (str[0]) { case 'n': cin >> id1; ml.insert(Map::value_type(id1, list<int>())); break; case 'a': cin >> id1 >> num; ml[id1].push_back(num); break; case 'm': cin >> id1 >> id2; ml[id1].merge(ml[id2]); break; case 'u': cin >> id1; ml[id1].sort(); ml[id1].unique(); break; case 'o': cin >> id1; ml[id1].sort(); for (i = ml[id1].begin(); i != ml[id1].end(); i++) { cout << *i << " "; } cout << endl; break; } } return 0; }
B: set
- 总时间限制:
- 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行,每行按要求输出。
- 例子输入
-
7 add 1 add 1 ask 1 ask 2 del 2 del 1 ask 1
- 例子输出
-
1 2 1 2 0 0 0 2 1 0
#include <iostream> #include <set> #include <string> using namespace std; typedef multiset<int> MS; int main() { MS ms; set<int> s; int n, num; string str; cin >> n; while (n--) { cin >> str; if (str == "add") { cin >> num; s.insert(num); ms.insert(num); cout << ms.count(num) << endl; } else if (str == "ask") { cin >> num; if (s.count(num)) cout << "1" << " "; else cout << "0" << " "; cout << ms.count(num) << endl; } else if (str == "del") { cin >> num; cout << ms.count(num) << endl; ms.erase(num); } } return 0; }
C:字符串操作
- 总时间限制:
- 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结束。
- 输出
-
依据操作提示输出相应字符串。
- 例子输入
-
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
- 例子输出
-
Op29adfk48 358 329strjvc Op29adfk48 35a8
#include <iostream> #include <string> #include <vector> #include <sstream> using namespace std; vector<string> svec; int getN(string s); string getStr(string str); bool isInt(string str); int find(); int rfind(); string copy(); string add(); void insert(); void reset(); void print(); void printall(); int main() { int n; string str; cin >> n; while (n--) { cin >> str; svec.push_back(str); } while (1) { cin >> str; if (str == "over") break; if (str == "copy") copy(); else if (str == "add") add(); else if (str == "find") find(); else if (str == "rfind") rfind(); else if (str == "insert") insert(); else if (str == "reset") reset(); else if (str == "print") print(); else if (str == "printall") printall(); } return 0; } int getN(string s) { if (s == "find") return find(); else if (s == "rfind") return rfind(); else return s[0] - '0'; } string getStr(string str) { if (str == "add") return add(); else if (str == "copy") return copy(); else return str; } int find() { string s,str; cin >> s; s = getStr(s); int n; cin >> str; n = getN(str); if (svec[n-1].find(s) == string::npos) return svec[n-1].size(); return svec[n-1].find(s); } int rfind() { string s, str; cin >> s; s = getStr(s); int n; cin >> str; n = getN(str); if (svec[n-1].rfind(s) == string::npos) return svec[n-1].size(); return svec[n-1].rfind(s); } string copy() { int N[3]; string str; for (int i = 0; i < 3; i++) { cin >> str; N[i] = getN(str); } return svec[N[0]-1].substr(N[1], N[2]); } bool isInt(string str) { if (str.size() > 5) return false; for (int i = 0; i < str.size(); i++) { if (!(str[i] >= '0' && str[i] <= '9')) return false; } return true; } string add() { string str, s[2]; for (int i = 0; i < 2; i++) { cin >> s[i]; s[i] = getStr(s[i]); } if (isInt(s[1]) && isInt(s[0])) { int a = atoi(s[0].c_str()); int b = atoi(s[1].c_str()); int c = a + b; stringstream ss; ss << c; ss >> str; return str; } return s[0] + s[1]; } void insert() { string s; cin >> s; s = getStr(s); int n, x; string temp; cin >> temp; n = getN(temp); cin >> temp; x = getN(temp); svec[n-1].insert(x, s); } void reset() { string s, str; cin >> s; s = getStr(s); int n; cin >> str; n = getN(str); svec[n-1].assign(s); } void print() { string s; int n; cin >> s; n = getN(s); cout << svec[n-1] << endl; } void printall() { for (int i = 0; i < svec.size(); i++) cout << svec[i] << endl; }
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描写叙述
-
为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家热血格斗场。格斗场实行会员制,可是新来的会员不须要交入会费,而仅仅要同一名老会员打一场表演赛,证明自己的实力。
我们如果格斗的实力能够用一个正整数表示,成为实力值。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每个新队员都会选择与他实力最为接近的人比赛,即比赛两方的实力值之差的绝对值越小越好,如果有两个人的实力值与他区别同样,则他会选择比他弱的那个(显然,虐人必被虐好)。
不幸的是,Facer一不小心把比赛记录弄丢了,可是他还保留着会员的注冊记录。如今请你帮facer恢复比赛纪录,依照时间顺序依次输出每场比赛两方的id。
- 输入
-
第一行一个数n(0 < n <=100000),表示格斗场新来的会员数(不包含facer)。以后n行每一行两个数,依照入会的时间给出会员的id和实力值。一開始,facer就算是会员,id为1,实力值1000000000。输入保证两人的实力值不同。
- 输出
-
N行,每行两个数,为每场比赛两方的id,新手的id写在前面。
- 例子输入
-
3 2 1 3 3 4 2
- 例子输出
-
2 1 3 2 4 2
#include <cstdio> #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; member[1000000000] = 1; int id1 = 0, id2 = 0, s1 = 0, s2 = 0; id1 = 1; s1 = 1000000000; int n; scanf("%d", &n); while (n--) { scanf("%d %d", &id, &strength); member[strength] = id; pairs = member.insert(MAP::value_type(strength, id)); MAP::iterator i = pairs.first; if (i == member.begin()) { i++; printf("%d %d\n", id, i->second); continue; } else { i--; id1 = i->second; s1 = i->first; } i++, i++; if (i != member.end()) { id2 = i->second; s2 = i->first; } if (abs(s2 - strength) == abs(s1 - strength)) { if (s1 < s2) printf("%d %d\n", id, id1); else printf("%d %d\n", id, id2); } else if ((abs(s1 - strength) < abs(s2 - strength)) || i == member.end()) { printf("%d %d\n", id, id1); } else printf("%d %d\n", id, id2); } return 0; }
- 总时间限制:
- 2500ms
- 内存限制:
- 131072kB
- 描写叙述
-
我们定义一个正整数a比正整数b优先的含义是:
*a的质因数数目(不包含自身)比b的质因数数目多;
*当两者质因数数目相等时,数值较大者优先级高。
如今给定一个容器,初始元素数目为0,之后每次往里面加入10个元素,每次加入之后,要求输出优先级最高与最低的元素,并把该两元素从容器中删除。
- 输入
-
第一行: num (加入元素次数,num <= 30)
以下10*num行,每行一个正整数n(n < 10000000).
- 输出
-
每次输入10个整数后,输出容器中优先级最高与最低的元素,两者用空格间隔。
- 例子输入
-
1 10 7 66 4 5 30 91 100 8 9
- 例子输出
-
66 5
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cmath> #include <set> using namespace std; bool isPrime(int iVal) { for (int i = 2; i <= sqrt(iVal); i++) { if (iVal % i == 0) return false; } return true; } int getFactor(int a) { int sum = 0; int k = 0; for (int i = 2; i <= sqrt(a); i++) { if (a % i == 0) { k = a / i; if (i != k && isPrime(k)) sum += 1; if (isPrime(i)) { sum += 1; } } } return sum; } class Compare_Class_Up { public: bool operator()(const int& a, const int& b) { int sumA = 0, sumB = 0; sumA = getFactor(a); sumB = getFactor(b); if (sumA == sumB) { if (a < b) { return true; } else return false; } else if (sumA > sumB) { return false; } else return true; } }; int main() { set<int, Compare_Class_Up> queue; int n = 0; scanf("%d", &n); while (n--) { int num; for (int i = 0; i < 10; i++) { scanf("%d", &num); queue.insert(num); } int min = *(queue.begin()); int max = *(queue.rbegin()); queue.erase(max); queue.erase(min); printf("%d %d\n",max, min); } return 0; }