点我进入代码提交OJ
• STL(Standard Template Library),也被称为标准模板库,包含大量的模板类和模板函数,是C++提供的一个由一些容器、算法和其他一些组件组成的集合。用于完成诸如输入/输出、数学计算等功能。
• STL被内置到支持C++的编译器中。在C++标准中,STL被组织为13个头文件:,
STL有两类共七种基本容器类型。
• 序列式容器,此为可序群集,其中每个元素的位置取决于插入的顺序,和元素值无关。STL提供三个序列式容器:向量(vector)、双端队列(deque)、列表(list),此外,string和array也可以被视为序列式容器。
• 关联式容器,此为已序群集,其中每个元素位置取决于特定的排序准则以及元素值,和插入次序无关。STL提供了四个关联式容器:集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)。
• vector容器被称为向量容器,是一种序列式容器。vector容器和数组非常类似,但比数组优越,vector实现的是一个动态数组,在进行元素的插入和删除的过程中,vector会动态调整所占用的内存空间。在中间插入和删除慢,但在末端插入和删除快。
• 在创建vector容器之前,程序中要包含如下内容:
#include
using namespace std;
• 创建vector容器的方式有很多,基本形式为vector ,其中T表示存储元素的类型;例如,vector
• 容器deque和容器vector都是序列式容器,都是采用动态数组来管理元素,能够快速地随机访问任一个元素,并且能够在容器的尾部快速地插入和删除元素。不同之处在于,deque还可以在容器首部快速地插入、删除元素。因此,容器deque也被称为双端队列。
• 使用deque容器之前要加上
• map是STL的一个关联容器, 一个map是一个键值(key, value)对的序列,key和value可以是任意的类型。在一个map中key值是唯一的。map提供一对一的数据处理能力,在编程需要处理一对一数据的时候,可以采用map进行处理。
• 使用map容器,首先,程序要有包含map类所在的头文件:#include
• 集合(set),就是具有共同性质的一些对象汇集成一个整体。set容器用于存储同一数据类型的元素,并且能从中取出数据。在set中每个元素的值唯一,而且系统能根据元素的值自动进行排序。
• 使用set容器,首先,程序要有包含set类所在的头文件:#include
Many areas of Computer Science use simple, abstract domains for both analytical and empirical studies. For example, an early AI study of planning and robotics (STRIPS) used a block world in which a robot arm performed tasks involving the manipulation of blocks.
In this problem you will model a simple block world under certain rules and constraints. Rather than determine how to achieve a specified state, you will “program” a robotic arm to respond to a limited set of commands.
The problem is to parse a series of commands that instruct a robot arm in how to manipulate blocks that lie on a flat table. Initially there are n blocks on the table (numbered from 0 to n-1) with block bi adjacent to block bi+1 for all 0 <= i < n-1 as shown in the diagram below:
The valid commands for the robot arm that manipulates blocks are:
move a onto b
where a and b are block numbers, puts block a onto block b after returning any blocks that are stacked on top of blocks a and b to their initial positions.
move a over b
where a and b are block numbers, puts block a onto the top of the stack containing block b, after returning any blocks that are stacked on top of block a to their initial positions.
pile a onto b
where a and b are block numbers, moves the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto block b. All blocks on top of block b are moved to their initial positions prior to the pile taking place. The blocks stacked above block a retain their order when moved.
pile a over b
where a and b are block numbers, puts the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto the top of the stack containing block b. The blocks stacked above block a retain their original order when moved.
quit
terminates manipulations in the block world.
Any command in which a = b or in which a and b are in the same stack of blocks is an illegal command. All illegal commands should be ignored and should have no affect on the configuration of blocks.
Input
The input begins with an integer n on a line by itself representing the number of blocks in the block world. You may assume that 0 < n < 25.
The number of blocks is followed by a sequence of block commands, one command per line. Your program should process all commands until the quit command is encountered.
You may assume that all commands will be of the form specified above. There will be no syntactically incorrect commands.
Output
The output should consist of the final state of the blocks world. Each original block position numbered i ( 0 <= i < n where n is the number of blocks) should appear followed immediately by a colon. If there is at least a block on it, the colon must be followed by one space, followed by a list of blocks that appear stacked in that position with each block number separated from other block numbers by a space. Don’t put any trailing spaces on a line.
There should be one line of output for each block position (i.e., n lines of output where n is the integer on the first line of input).
Sample Input
10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
quit
Sample Output
0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:
输入整数n,表示有编号为0~n-1的木块,分别放在顺序排列编号为0~n-1的位置。
设a和b是木块块号。现对这些木块进行操作,操作指令有如下四种:
• move a onto b:把a、b上的木块放回各自原来的位置,再把a放到b上;
• move a over b:把a上的木块放回各自的原来的位置,再把a放到包含了b的堆上;
• pile a onto b:把b上的木块放回各自的原来的位置,再把a以及在a上面的木块放到b上;
• pile a over b:把a连同a上木块放到包含了b的堆上。
当输入quit时,结束操作并输出0~n-1位置上的木块情况。
在操作指令中,如果a = b,其中a和b在同一堆块,则该操作指令是非法指令。非法指令要忽略,并且不应影响块的放置。
• 输入
输入的第一行给出一个整数n,表示木块的数目。本题设定0 < n < 25。
然后给出一系列操作指令,每行一个操作指令。您的程序要处理所有命令直到遇到quit指令。
本题设定,所有的操作指令都是上面给出的格式,不会有语法错误的指令。
• 输出
输出给出木块的最终状态。每个原始块位置i(0<=i
• 本题用vector容器vector
• 首先,设计两个函数:find_pile_height(int a, int &p, int &h),返回木块a所在的堆号p以及a的高度h;clear_above(int p, int h),把第p堆第h个木块以上的木块放置到原来位置。然后,在这两个函数,以及vector容器的成员函数size()和push_back()的基础上,根据操作指令的规则,每种操作指令都用一个函数实现。最后,在主程序中逐条实现操作指令。
#include
#include
#include
using namespace std;
int n;
vector<int> v[24]; //相当于一个二维数组,列确定,每列的行(木块数)不确定
void find_pile_height(int a,int& p,int& h) //找到木块a所在的堆号p以及a的高度h
{
for(p=0;p<n;p++)
for(h=0;h<v[p].size();h++) //vector容器的成员函数size(),返回元素个数
if(v[p][h]==a)
return;
}
void clear_above(int p,int h) //把第p堆第h个木块以上的木块放置到原来位置
{
for(int i=h+1;i<v[p].size();i++)
{
int b=v[p][i];
v[b].push_back(b); //vector容器的成员函数push_back(),在序列尾部添加元素
}
v[p].resize(h+1); //vector容器的成员函数resize(),只保留0~h个元素
}
void moveOnto(int a,int b) //move a onto b:把a、b上的木块放回各自原来的位置,再把a放到b上
{
int pa,ha,pb,hb;
find_pile_height(a,pa,ha); //找到木块a和b所在的堆号以及高度h
find_pile_height(b,pb,hb);
if(pa!=pb) //a和b不在同一堆,则操作
{
clear_above(pa,ha); //a和b所在的堆中
clear_above(pb,hb);
v[pb].push_back(a);
v[pa].resize(ha);
}
}
void moveOver(int a,int b) //move a over b:把a上的木块放回各自的原来的位置,再把a放到包含了b的堆上
{
int pa,ha,pb,hb;
find_pile_height(a,pa,ha);
find_pile_height(b,pb,hb);
if(pa!=pb)
{
clear_above(pa,ha);
v[pb].push_back(a);
v[pa].resize(ha);
}
}
void pileOnto(int a,int b) //pile a onto b:把b上的木块放回各自的原来的位置,再把a以及在a上面的木块放到b上
{
int pa,ha,pb,hb;
find_pile_height(a,pa,ha);
find_pile_height(b,pb,hb);
if(pa!=pb)
{
clear_above(pb,hb);
for(int i=ha;i<v[pa].size();i++)
v[pb].push_back(v[pa][i]);
v[pa].resize(ha);
}
}
void pileOver(int a,int b) //pile a over b:把a连同a上的木块放到包含了b的堆上
{
int pa,ha,pb,hb;
find_pile_height(a,pa,ha);
find_pile_height(b,pb,hb);
if(pa!=pb)
{
for(int i=ha;i<v[pa].size();i++)
v[pb].push_back(v[pa][i]);
v[pa].resize(ha);
}
}
int main()
{
int i,j;
cin >> n; //n:木块的数目
for(i=0;i<n;i++) //初始化,0~n-1的木块放到0~n-1的位置
v[i].push_back(i); //push_back():在序列v[i]尾部添加木块i
int a,b; //木块a和b的块号
string str1,str2; //操作指令中的字符串
cin >> str1;
while(str1 != "quit") //每次循环处理一条操作指令
{
cin >> a >> str2 >> b;
if(str1=="move" && str2=="onto")
moveOnto(a,b);
if(str1=="move" && str2=="over")
moveOver(a,b);
if(str1=="pile" && str2=="onto")
pileOnto(a,b);
if(str1=="pile" && str2=="over")
pileOver(a,b);
cin >> str1;
}
for(i=0;i<n;i++) //输出木块的最终状态
{
cout << i << ":";
for(j=0;j<v[i].size();j++)
cout << " " << v[i][j];
cout << endl;
}
return 0;
}
• 您正在用一个坏键盘键入一个长文本。这个键盘的问题是时不时“Home”键或“End”键会在您输入文本时自动按下。您并没有意识到这个问题,因为你只关注文本,甚至没有打开显示器。完成键入后,您打开显示器,在屏幕上看到文本。在中文里,我们称之为悲剧。请您是找到悲剧的文本。
• 输入
输入给出若干测试用例。每个测试用例都是一行,包含至少一个,最多100,000个字母、下划线和两个特殊字符‘[’和‘]’;其中‘[’表示“Home”键,而‘]’表示“End”键。输入以EOF结束。
• 输出
对于每个测试用例,输出在屏幕上的悲剧的文本。
• 本题题意:对于每个输入的字符串,如果出现’ [ ‘,则输入光标就跳到字符串的最前面,如果出现’ ] ',则输入光标就跳到字符串的最后面。输出实际上显示在屏幕上的字符串。
• 本题可以用双端队列模拟试题描述给出的规则,用字符串变量s存储输入的字符串,deque容器deque
• 最后,从deque容器dq中逐个输出字符。
• 本题的参考程序用到字符串操作函数clear(),删除全部字符;size(),返回字符数量;以及c_str(),将内容以C_string返回。
#include
#include
#include
using namespace std;
string s,temp;
deque<string> dp; //创建一个空的deque容器dp
int main()
{
while(cin >> s) //每个测试用例一行字符串s
{
char op=0;
int i;
temp.clear(); //清空字符串temp
for(i=0;i<s.size();i++) //对s中的字符逐个处理
{
if(s[i]=='[' || s[i]==']') //deque容器dp实现规则
{
if(op=='[')
dp.push_front(temp); //deque容器的成员函数push_front(),将中间字符串temp的内容插入到deque容器dq的首部
else
dp.push_back(temp); //deque容器的成员函数push_back(),将中间字符串temp的内容插入到deque容器dq的尾部
temp.clear();
op=s[i];
}
else
temp+=s[i];
if(i==s.size()-1) //处理在中间字符串temp的最后一段字符串
{
if(op=='[')
dp.push_front(temp);
else
dp.push_back(temp);
temp.clear();
}
}
while(!dp.empty()) //从deque容器dq中逐个输出字符
{
printf("%s",dp.front().c_str());//deque容器的成员函数front(),容器的第一个元素的引用:c_str():将内容以C_string返回
dp.pop_front(); //deque容器的成员函数pop_front(),删除首部数据
}
puts("");
}
return 0;
}
You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect of a foreign language. Fortunately, you have a dictionary to help you understand them.
Input
Input consists of up to 100,000 dictionary entries, followed by a blank line, followed by a message of up to 100,000 words. Each dictionary entry is a line containing an English word, followed by a space and a foreign language word. No foreign word appears more than once in the dictionary. The message is a sequence of words in the foreign language, one word on each line. Each word in the input is a sequence of at most 10 lowercase letters.
Output
Output is the message translated to English, one word per line. Foreign words not in the dictionary should be translated as “eh”.
Sample Input
dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay
atcay
ittenkay
oopslay
Sample Output
cat
eh
loops
Hint
Huge input and output,scanf and printf are recommended.
• 您离开Waterloo到另外一个大城市。那里的人们说着一种让人费解的外语。不过幸运的是,您有一本词典可以帮助你来理解这种外语。
• 输入
首先输入一个词典,词典中包含不超过100000个词条,每个词条占据一行。每一个词条包括一个英文单词和一个外语单词,在两个单词之间用一个空格隔开。而且在词典中不会有某个外语单词出现超过两次。词典之后是一个空行,然后给出不超过100000个外语单词,每个单词一行。输入中出现单词只包括小写字母,而且长度不会超过10。
• 输出
在输出中,请您把输入的单词翻译成英文单词,每行输出一个英文单词。如果某个外语单词不在词典中,就把这个单词翻译成“eh”。
• 本题需要处理一对一(英文单词、外语单词)数据,所以使用map容器mp,key和value的类型是string。首先,输入词典,以外语单词为key,英文单词为value,在map中插入词条(mp[Foreign]=English);然后,输入要查询的外语单词,从map容器mp中,获取英文单词(mp[Foreign])。
#include //包含map类所在的头文件
#include
#include
using namespace std;
int main()
{
char english[10],foreign[10]; //english:英文单词,foreign:外语单词
char str[25]; //输入的字符串
map<string,string>mp; //定义map容器mp
while(gets(str) && str[0]!='\0') //输入词典:每次循环一个词条;空行:词典结束
{
sscanf(str,"%s %s",english,foreign);//sscanf:以固定字符串为输入源
mp[foreign]=english; //在map中插入元素,用数组方式插入值
}
while(gets(str) && str[0]!='\0') //每次循环处理一个要查询的外语单词
{
sscanf(str,"%s",foreign);
if(mp[foreign] != "\0") //获取map中的元素
cout << mp[foreign] << endl;
else
cout << "eh" << endl;
}
return 0;
}
• 大多数填字游戏迷熟悉变形词(anagrams)——一组有着相同的字母但字母位置不同的单词,例如OPTS, SPOT, STOP, POTS和POST。有些单词没有这样的特性,无论您怎样重新排列其字母,都不可能构造另一个单词。这样的单词被称为非变形词(ananagrams),例如QUIZ。
• 当然,这样的定义是要基于您所工作的领域的。例如,您可能认为ATHENE是一个非变形词,而一个化学家则会很快地给出ETHANE。一个可能的领域是全部的英语单词,但这会导致一些问题。如果将领域限制在Music中,在这一情况下,SCALE是一个相对的非变形词(LACES不在这一领域中),但可以由NOTE产生TONE,所以NOTE不是非变形词。
• 请您编写一个程序,输入某个限制领域的词典,并确定相对非变形词。注意单字母单词实际上也是相对非变形词,因为它们根本不可能被“重新安排”。字典包含不超过1000个单词。
• 输入
输入由若干行组成,每行不超过80个字符,且每行包含单词的个数是任意的。单词由不超过20个的大写和/或小写字母组成,没有下划线。空格出现在单词之间,在同一行中的单词至少用一个空格分开。含有相同的字母,而大小写不一致的单词被认为彼此是变形词,如tIeD和EdiT是变形词。以一行包含单一的#作为输入终止。
• 输出
输出由若干行组成,每行给出输入字典中的一个相对非变形词的单词。单词输出按字典序(区分大小写)排列。至少有一个相对非变形词。
• 若当前单词的升序串与某单词的升序串相同,则说明该单词是相对变形词;若当前单词的升序串不同于所有其它单词的升序串,则该单词是非相对变形词。由此给出算法:
• 首先,通过函数getkey(string& s),输入的字符串s中的字母改为小写字母,并按字母升序排列;然后,在map容器dict中,用数组方式插入处理后的字符串,累计字符串的重复次数值;而输入的原始字符串添加到vector容器words中。接下来,对vector容器words中的每个字符串进行判断,如果是非相对变形词,则插入到vector容器ans中;最后,对vector容器ans中的所有相对非变形词按字典序进行排列,然后输出。
#include
#include
#include
#include
using namespace std;
map<string,int> dict;
vector<string> words;
vector<string> ans;
string getkey(string& s) //输入字符串改为小写字母,按字母升序排列
{
string key=s;
for(int i=0;i<key.length();i++)
key[i]=tolower(key[i]); //tolower():把给定的字母转换为小写字母
sort(key.begin(),key.end()); //字符串按升序排列
return key;
}
int main()
{
string s;
int i;
while(cin >> s && s[0] != '#') //每次循环,处理一个输入的字符串
{
string key=getkey(s);
dict[key]++; //map容器dict中,累计key的重复次数
words.push_back(s); //push_back():在vector容器words的最后添加输入的字符串s
}
for(i=0;i<words.size();i++) //vector容器words中的每个字符串
if(dict[getkey(words[i])]==1)//非相对变形词
ans.push_back(words[i]);
sort(ans.begin(),ans.end());
for(i=0;i<ans.size();i++) //输出非相对变形词
cout << ans[i] << "\n";
return 0;
}
一种语言是一个字符串组成的集合。两种语言的拼接是在第一种语言的字符串的结尾处拼接第二种语言的字符串而构成的所有字符串的集合。
例如,如果给出两种语言A和B:
• A = {cat, dog, mouse};
• B = {rat, bat};
则A和B的连接是:
• C = {catrat, catbat, dograt, dogbat, mouserat, mousebat}。
给出两种语言,请您计算两种语言拼接所产生的字符串的数目。
• 输入
输入有多个测试用例。输入的第一行给出测试用例的数目T(1≤T≤25)。接下来给出T个测试用例。每个测试用例的第一行给出两个整数,M和N(M, N < 1500),是每种语言中字符串的数量。然后,M行给出第一种语言的字符串;接下来的N行给出了第二种语言的字符串。本题设定字符串仅由小写字母(‘a’到’z’)组成,长度小于10个字符,并且每个字符串在一行中给出,没有任何前导或尾随的空格。
输入语言中的字符串可能不会被排序,并且不会有重复的字符串。
• 输出
对于每个测试用例,输出一行。每个测试用例的输出是以测试用例的序列号开始,然后给出在第一种语言的字符串之后拼接第二种语言中的字符串所产生的字符串数。
• 本题采用set容器存储两种语言拼接之后所产生的字符串集合,“set
• 对于每个测试用例,将第一种语言的字符串和第二种语言的字符串拼接,产生的字符串插入set容器s1中;然后,通过方法size()返回拼接所产生的字符串数。
#include
#include
#include
using namespace std;
char str1[1500][10]; //第一种语言的字符串
char str2[1500][10]; //第二种语言的字符串
int main()
{
int cas=1; //测试用例序号
set<string>s1; //两种语言的字符串拼接后所产生的字符串集合
int t,i,j;
scanf("%d",&t); //输入测试用例数
while(t--) //每次循环处理一个测试用例
{
int n,m; //两种语言中的字符串数量
scanf("%d%d",&n,&m);
getchar(); //读取多余的回车符
for(i=0;i<n;i++) //输入第一种语言的字符串
gets(str1[i]);
for(i=0;i<m;i++) //输入第二种语言的字符串
gets(str2[i]);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
char tmp[20]; //两个字符串连接所产生的字符串
strcpy(tmp,str1[i]);
strcat(tmp,str2[j]);
s1.insert(tmp); //拼接产生的字符串插入集合s1
}
printf("Case %d: %d\n",cas++,s1.size()); //集合s1中的元素数
s1.clear(); //清空集合s1
}
return 0;
}
• Spot游戏在一个NN的棋盘上进行,如图所示的Spot游戏,N=4。在游戏的过程中,两个玩家交替,一次走一步:一个玩家一次可以在一个空方格中放置一枚黑色的棋子(点),也可以从棋盘上取走一枚棋子,从而产生各种各样的棋盘图案。如果一个棋盘图案(或其旋转90度或180度)在游戏中被重复,则产生该图案的玩家就失败,而另一个玩家获胜。如果在此之前没有重复的图案产生,在2N步后,游戏平局。
• 如果第一个图案是在早些时候产生的,那么产生后面三个图案中的任何一个(还有一个,第一个图案旋转180度,没有给出),都会终止游戏;而产生最后一个图案则不会结束游戏。
• 输入
输入给出一系列的游戏,每局游戏首先在一行中给出棋盘的大小N,(2N50);然后给出玩家的2N步,无论它们是否是必要的。每一步先给出一个正方形的坐标(1…N范围内的整数),然后给出一个空格,以及一个分别表示放置一枚棋子或拿走一枚棋子的字符“+”或“-”。本题设定玩家的每一步都是合法的,也就是说,不会在一个已经放置了棋子的方格里再放置一枚棋子,也不会从一个不存在棋子的方格里拿走棋子。输入将以零(0)为结束。
• 输出
对于每局游戏,输出一行,表明哪位选手赢了,以及走到哪一步,或者比赛以平局结束。
• 在参考程序中,棋局表示为一个结构。每输入一个棋局,就将这一个棋局的四种旋转都存储在一个集合中。这样,对于棋局序列中的每个棋局,可以判断该棋局是否在集合中存在,如果已经存在,则根据步数判定赢家。走完2N步,没有重复棋局,则为平局。
• 由于set的具体实现采用了红黑树的平衡二叉树的数据结构,所以,set中的元素就有大小比较。在参考程序中,给出重载函数booloperator < (const spot& a, const spot& b),以比较两个结构的大小,便于在set中插入和查找元素。
#include
#include
#include
using namespace std;
const int nmax=51;
int n;
struct spot
{
bool arr[nmax][nmax];
}p;
bool operator < (const spot& a,const spot& b) //重载函数
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(a.arr[i][j] < b.arr[i][j])
return true;
else if(a.arr[i][j] > b.arr[i][j])
return false;
return false;
}
void changs(spot& w) //将棋局逆时针旋转90°
{
spot a;
for(int i=0;i<=n;i++)
for(int j=1;j<=n;j++)
a.arr[i][j]=w.arr[j][n+1-i];
w=a;
}
int main()
{
int a,b;
char c;
while(scanf("%d",&n) && n)
{
bool flag=false; //棋局重复标志
set<spot>s; //把棋局(二维数组)的结构体作为集合元素
memset(p.arr,false,sizeof(p.arr));
int count=0;
for(int num=1;num<=2*n;num++)
{
scanf("%d%d %c",&a,&b,&c); //输入每一步
if(flag)
continue;
if(c=='+') //放置棋子
p.arr[a][b]=true;
else //取走棋子
p.arr[a][b]=false;
if(s.count(p)) //当前棋局在集合中已经有了
{
flag=true;
count=num; //走了几步
continue;
}
spot t(p);
for(int j=0;j<4;j++) //将棋局旋转的四种情况插入到set里面
{
s.insert(t);
changs(t);
}
}
if(flag) //棋局重复,判定赢家
if(count%2 == 0)
printf("Player 1 wins on move %d\n",count);
else
printf("Player 2 wins on move %d\n",count);
else
printf("Draw\n");
}
return 0;
}
Frosh commencing their studies at Waterloo have diverse interests, as evidenced by their desire to take various combinations of courses from among those available.
University administrators are uncomfortable with this situation, and therefore wish to offer a conformity prize to frosh who choose one of the most popular combinations of courses. How many frosh will win the prize?
Input
The input consists of several test cases followed by a line containing 0. Each test case begins with an integer 1 ≤ n ≤ 10000, the number of frosh. For each frosh, a line follows containing the course numbers of five distinct courses selected by the frosh. Each course number is an integer between 100 and 499.
The popularity of a combination is the number of frosh selecting exactly the same combination of courses. A combination of courses is considered most popular if no other combination has higher popularity.
Output
For each line of input, you should output a single line giving the total number of students taking some combination of courses that is most popular.
Sample Input
3
100 101 102 103 488
100 200 300 101 102
103 102 101 488 100
3
200 202 204 206 208
123 234 345 456 321
100 200 300 400 444
0
Sample Output
2
3
• 在Waterloo大学,一年级的新生们开始了学业,他们有着不同的兴趣,他们要从现有的课程中选择不同的课程组合,进行选修。
• 大学的领导层对这种情况感到不安,因此他们要为选修最受欢迎的课程组合之一的一年级新生颁奖。会有多少位一年级新生获奖呢?
• 输入
输入由若干个测试用例组成,在测试用例的最后给出包含0的一行。每个测试用例首先给出一个整数1≤n≤10000,表示一年级新生的数量。对于每一个一年级新生,后面都会给出一行,包含这位新生选修的五个不同课程的课程编号。每个课程编号是100到499之间的整数。
课程组合的受欢迎程度是选择完全相同的课程组合的一年级新生的数量。如果没有其他的课程组合比某个课程组合更受欢迎,那么这个课程组合被认为是最受欢迎的。
• 输出
对于每一个测试用例,输出一行,给出选修最受欢迎的课程组合的学生总数。
• 有n位学生选课,每位学生选修5门课,有5个不同的课程号。要求找出选修最受欢迎的课程组合的学生数量;如果有多个课程组合是最受欢迎的,则计算选修这些组合的学生总数。
• 一个学生选课的5个不同的课程号,用STL的set(集合)容器suit来存储;而n位学生选课,则STL的map容器count来存储,map将相同集合(相同的课程组合)存储在同一位置,在存入一个集合时,该集合出现次数增加1。同时,记录出现最多的课程组合的次数M,以及出现次数为M的课程组合数MC。最后输出M*MC。
#include
#include
#include
using namespace std;
int main()
{
int n; //n位学生选课
while(cin >> n,n)
{
map<set<int>,int> count;
int m=0,mc=0,i;
while(n--)
{
set<int> suit;
for(i=0;i<5;i++) //一个学生选课的5个不同的课程号
{
int cour;
cin >> cour;
suit.insert(cour); //在集合suit中插入元素
}
count[suit]++; //集合出现次数增加1
int h=count[suit];
if(h==m)
mc++;
if(h>m)
m=h,mc=1;
}
cout << m*mc << endl;
}
return 0;
}