寒假集训1.25

寒假集训

A - The Blocks Problem

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:
题目大意:根据输入入要求的操作移动木块
思路:模拟操作
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的堆上。
可以发现,有onto操作的,就要把b上的木块放回各自原来的位置
主要代码:

void get_height(int a,int &p,int &h){//寻找木块高度,位置 
	for(p = 0;p<n;++p){
		for(h=0;h<v[p].size();++h)
		  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 tmp = v[p][i];
		v[tmp].push_back(tmp);
	}
	v[p].resize(h+1);
}
//移动位置p上高度h及以上的木块到位置p2上
void move(int p,int h,int p2){
	for(int i = h;i<v[p].size();++i)
	    v[p2].push_back(v[p][i]);
	v[p].resize(h);
}

完整代码:

#include<iostream>
#include<vector>
#include<string> 
using namespace std;
vector<int>v[25];
int n;
void get_height(int a,int &p,int &h){//寻找木块高度,位置 
	for(p = 0;p<n;++p){
		for(h=0;h<v[p].size();++h)
		  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 tmp = v[p][i];
		v[tmp].push_back(tmp);
	}
	v[p].resize(h+1);
}
//移动位置p上高度h及以上的木块到位置p2上
void move(int p,int h,int p2){
	for(int i = h;i<v[p].size();++i)
	    v[p2].push_back(v[p][i]);
	v[p].resize(h);
}
int main(){
	cin>>n;
	int a,b;
	string s1,s2;
	for(int i = 0; i<n;++i)
	    v[i].push_back(i);
	while(cin>>s1&&s1!="quit"){
		cin>>a>>s2>>b;
		int pa,ha,pb,hb;
		get_height(a,pa,ha);
		get_height(b,pb,hb);
		if(pa==pb) continue;
		if(s1=="move") clear_above(pa,ha);
		if(s2=="onto") clear_above(pb,hb);
		move(pa,ha,pb);
	}
	    for(int i = 0; i < n; ++i){
        printf("%d:", i);
        for(int j = 0; j < v[i].size(); ++j)
            printf(" %d", v[i][j]);
        printf("\n");
    }
	return 0;
}

B - Broken Keyboard

You’re typing a long text with a broken keyboard. Well it’s not so badly broken. The only problem
with the keyboard is that sometimes the “home” key or the “end” key gets automatically pressed
(internally).
You’re not aware of this issue, since you’re focusing on the text and did not even turn on the
monitor! After you finished typing, you can see a text on the screen (if you turn on the monitor).
In Chinese, we can call it Beiju. Your task is to find the Beiju text.
Input
There are several test cases. Each test case is a single line containing at least one and at most 100,000
letters, underscores and two special characters ‘[’ and ‘]’. ‘[’ means the “Home” key is pressed
internally, and ‘]’ means the “End” key is pressed internally. The input is terminated by end-of-file
(EOF).
Output
For each case, print the Beiju text on the screen.
Sample Input
This_is_a_[Beiju]_text
[[]][][]Happy_Birthday_to_Tsinghua_University
Sample Output
BeijuThis_is_a__text
Happy_Birthday_to_Tsinghua_University

之前做过,这次用deque做法
思路:deque容器deque dq来产生在屏幕上的悲剧的文 本。在输入字符串s后,对s中的字符逐个处理:当前字符如果不是’ [ ’
或’ ] ‘,则当前字符加入到中间字符串str中(str+=s[i]);当前字
符如果是’ [ ‘,则中间字符串temp的内容插入到deque容器dq的首部;
当前字符如果是’ ] ',则中间字符串temp的内容插入到deque容器dq的
尾部。
• 最后,从deque容器dq中逐个输出字符
本题的参考程序用到字符串操作函数clear(),删除全部字符;size(),
返回字符数量;以及c_str(),将内容以C_string返回。
完整代码:

#include<iostream>
#include<deque>
#include<string>
using namespace std;
deque<string>dq;
int main(){
	string s;
	while(cin>>s){
		string str;
		char c;
		for(int i = 0; i<s.length();++i){
			if(s[i]=='['||s[i]==']'){
				if(c=='[')
				  dq.push_front(str);
			    else
			      dq.push_back(str);
			    str.clear();
			    c = s[i];
			}
			else 
			    str+=s[i];
			if(i==s.length()-1){
				if(c=='[')
				   dq.push_front(str);
				else
				   dq.push_back(str);
			str.clear(); 
			}
		}
		while(!dq.empty()){
			printf("%s",dq.front().c_str());
			dq.pop_front();
		}
		cout<<endl;
	}
	
	return 0;
}

C - Babelfish

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
题目大意:输入外语,输出词典对应的英语,如果没有对应的英语输出eh
思路:需要处理一对一(英文单词、外语单词)数据,所以使用
map容器mp,key和value的类型是string。首先,输入词典,以外
语单词为key,英文单词为value,在map中插入词条
(mp[Foreign]=English);然后,输入要查询的外语单词,从map
容器mp中,获取英文单词(mp[Foreign])
完整代码:

#include<iostream>
#include<string>
#include<map>
#include<cstdio>
#include<cstring>
using namespace std;
map<string, string>mp;
int main() {
	char str[25],s1[25],s2[25];
	while (1) {
		gets(str);
		if (str[0] == '\0') break;
		sscanf(str,"%s%s",s1,s2); 
		mp[s2] = s1;
	}
	while (gets(s1)) {
		if (mp[s1]=="")
			cout << "eh" << endl;
		else cout <<mp[s1]<< endl;
	}
	return 0;
}

D - Ananagrams

Most crossword puzzle fans are used to anagrams — groups of words with the same letters in different
orders — for example OPTS, SPOT, STOP, POTS and POST. Some words however do not have this
attribute, no matter how you rearrange their letters, you cannot form another word. Such words are
called ananagrams, an example is QUIZ.
Obviously such definitions depend on the domain within which we are working; you might think
that ATHENE is an ananagram, whereas any chemist would quickly produce ETHANE. One possible
domain would be the entire English language, but this could lead to some problems. One could restrict
the domain to, say, Music, in which case SCALE becomes a relative ananagram (LACES is not in the
same domain) but NOTE is not since it can produce TONE.
Write a program that will read in the dictionary of a restricted domain and determine the relative
ananagrams. Note that single letter words are, ipso facto, relative ananagrams since they cannot be
“rearranged” at all. The dictionary will contain no more than 1000 words.
Input
Input will consist of a series of lines. No line will be more than 80 characters long, but may contain any
number of words. Words consist of up to 20 upper and/or lower case letters, and will not be broken
across lines. Spaces may appear freely around words, and at least one space separates multiple words
on the same line. Note that words that contain the same letters but of differing case are considered to
be anagrams of each other, thus ‘tIeD’ and ‘EdiT’ are anagrams. The file will be terminated by a line
consisting of a single ‘#’.
Output
Output will consist of a series of lines. Each line will consist of a single word that is a relative ananagram
in the input dictionary. Words must be output in lexicographic (case-sensitive) order. There will always
be at least one relative ananagram.
Sample Input
ladder came tape soon leader acme RIDE lone Dreis peat
ScAlE orb eye Rides dealer NotE derail LaCeS drIed
noel dire Disk mace Rob dries

Sample Output
Disk
NotE
derail
drIed
eye
ladder
soo
题目大意:
大多数填字游戏迷熟悉变形词(anagrams)——一组有着相同的
字母但字母位置不同的单词,例如OPTS, SPOT, STOP, POTS和POST。
有些单词没有这样的特性,无论您怎样重新排列其字母,都不可
能构造另一个单词。这样的单词被称为非变形词(ananagrams),
例如QUIZ。
输入某个限制领域的词典,并确定相对非变
形词。注意单字母单词实际上也是相对非变形词,因为它们根本
不可能被“重新安排”。

思路:若当前单词的升序串与某单词的升序串相同,则说明该单词是相
对变形词;若当前单词的升序串不同于所有其它单词的升序串,
则该单词是非相对变形词。由此给出算法:
首先,通过函数getkey(string& s),输入的字符串s中的字母改为小
写字母,并按字母升序排列;然后,在map容器mp中,用数组方
式插入处理后的字符串,累计字符串的重复次数值;而输入的原
始字符串添加到vector容器w中。接下来,对vector容器w
中的每个字符串进行判断,如果是非相对变形词,则插入到
vector容器ans中;最后,对vector容器ans中的所有相对非变形词
按字典序进行排列,然后输出。
完整代码:

#include<bits/stdc++.h>
using namespace std;
vector<string>ans;
vector<string>w;
map<string,int>mp;
string getstr(string s){
	for(int i = 0; i<s.length();++i)
	    s[i] = tolower(s[i]);
	sort(s.begin(),s.end());
	return s;
}
int main(){
	string s;
	while(cin>>s&&s[0]!='#'){
		string str = getstr(s);
		w.push_back(s);
		mp[str]++;
	}
	for(int i = 0; i<w.size();++i){
		if(mp[getstr(w[i])]==1)
		ans.push_back(w[i]);
	}
	sort(ans.begin(),ans.end());
	for(int i = 0; i<ans.size();++i){
		cout<<ans[i]<<endl;
	}
	return 0;
}

F - Conformity

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大学,一年级的新生们开始了学业,他们有着不同的
兴趣,他们要从现有的课程中选择不同的课程组合,进行选修。
大学的领导层对这种情况感到不安,因此他们要为选修最受欢迎
的课程组合之一的一年级新生颁奖。会有多少位一年级新生获奖
呢?
课程组合的受欢迎程度是选择完全相同的课程组合的一年级新生的数
量。如果没有其他的课程组合比某个课程组合更受欢迎,那么这个课
程组合被认为是最受欢迎的。
思路:一种做法是用sets来存储一个学生选课的五个不同的课程号,n位学生选课,用map<set,int>mp存储,map将
相同集合(相同的课程组合)存储在同一位置,在存入一个集合
时,该集合出现次数增加1。同时,记录出现最多的课程组合的
次数maxx,以及出现次数为maxx的课程组合数m。最后输出m*maxx
完整代码:

#include<iostream>
#include<map>
#include<set>
using namespace std;
int n;
int main(){
	while(scanf("%d",&n)&&n){
	map<set<int>,int>mp;
	  int maxx=0/*最受欢迎的组合*/,m=0/*是否有多个最受欢迎的*/;
	  while(n--){	
		set<int>s;
		for(int i = 1; i<=5;++i){
			int c;
			scanf("%d",&c);
			s.insert(c);
		}
		mp[s]++;
		if(mp[s]==maxx) m++;
		if(mp[s]>maxx) maxx=mp[s],m=1;		
	  }
	  printf("%d\n",maxx*m);
	}
	return 0;
} 

不过这种做法在poj上是超时的,其他OJ不会
第二种做法:手写Hash,将五门课程数字升序排好序,再连成一个15位数字(每个课程三位数字),将这个数放进hash表中,统计最受欢迎的课程组的学生数量

完整代码:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod = 100007;
ll course[5];
ll hash[mod],pos[mod],pop[mod];
int getkey(ll num){
	int ct = num%mod;
	while(hash[ct]!=-1&&hash[ct]!=num)
	   ct = (ct+1)%mod;
	return ct;
}
int main(){
	int n;
	while(cin>>n&&n){
		ll ans = 0;
		fill(pop,pop+mod,0);
		fill(hash,hash+mod,-1);
		for(int i = 0; i<n;++i){
			for(int j = 0;j<5;++j)
			cin>>course[j];
			sort(course,course+5);
			ll ct = 0;
			for(int j = 0; j<5;++j)
			 ct = ct*1000+course[j];
			int cur = getkey(ct);
			hash[cur] = ct;
			ans = max(ans,++pop[pos[i]=cur]);
		}
		int cnt = 0;
		for(int j = 0;j<n;++j){
			if(pop[pos[j]]==ans)
			   cnt++;
		}
		cout<<cnt<<endl;
	}
	return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值