夏季训练DAY1(stl+模拟)
A题
http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2018
A - Game Rank
Description
The gaming company Sandstorm is developing an online two player game. You have been asked to implement the ranking system. All players have a rank determining their playing strength which gets updated after every game played. There are 25 regular ranks, and an extra rank, “Legend”, above that. The ranks are numbered in decreas- ing order, 25 being the lowest rank, 1 the second highest rank, and Legend the highest rank.
Each rank has a certain number of “stars” that one needs to gain before advancing to the next rank. If a player wins a game, she gains a star. If before the game the player was on rank 6-25, and this was the third or more consecutive win, she gains an additional bonus star for that win. When she has all the stars for her rank (see list below) and gains another star, she will instead gain one rank and have one star on the new rank.
For instance, if before a winning game the player had all the stars on her current rank, she will after the game have gained one rank and have 1 or 2 stars (depending on whether she got a bonus star) on the new rank. If on the other hand she had all stars except one on a rank, and won a game that also gave her a bonus star, she would gain one rank and have 1 star on the new rank. If a player on rank 1-20 loses a game, she loses a star. If a player has zero stars on a rank and loses a star, she will lose a rank and have all stars minus one on the rank below. However, one can never drop below rank 20 (losing a game at rank 20 with no stars will have no effect).
If a player reaches the Legend rank, she will stay legend no matter how many losses she incurs afterwards. The number of stars on each rank are as follows:
• Rank 25-21: 2 stars
• Rank 20-16: 3 stars
• Rank 15-11: 4 stars
• Rank 10-1: 5 stars
A player starts at rank 25 with no stars. Given the match history of a player, what is her rank at the end of the sequence of matches?
Input
There will be several test cases. Each case consists of a single line describing the sequence of matches. Each character corre- sponds to one game; ‘W’ represents a win and ‘L’ a loss. The length of the line is between 1 and 10 000 characters (inclusive).
Output
Output a single line containing a rank after having played the given sequence of games; either an integer between 1 and 25 or “Legend”.
Sample Input
WW
WWW
WWWW
WLWLWLWL
WWWWWWWWWLLWW
WWWWWWWWWLWWL
Sample Output
25
24
23
24
19
18
Hint
Source
NCPC2016
模拟题,题意稍复杂,大致为:
不同的排名下有不同的升名所需等级(大致同于现在许多游戏的段位),排名提升后,星数将变为1,当排名>=6时三连胜有额外的星奖励,在20名0星以及20名以后失败不掉星,20以内时,输一次掉一颗星,当无星可掉时便下降一个rank并且星数变为该rank满星少一颗。当排名达到第0(legend)时,胜败将不再影响他的排名。
代码如下:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
int limit(int a)
{
if(a<=25&&a>=21) return 2;
if(a<=20&&a>=16) return 3;
if(a>=11&&a<=15) return 4;
if(a<=10) return 5;
}
int main()
{
string s;
while(cin>>s)
{
int num=0,rank=25;
int len=s.length();
for(int i=0;i<len;i++)
{
if(s[i]=='W')
{
num++;
if(rank>=6&&i>1&&s[i-1]=='W'&&s[i-2]=='W')
num++;
if(num>limit(rank))
{
num-=limit(rank);
rank--;
}
}
else
{
if(rank>20||rank==20&&!num)
{
continue;
}
num--;
if(num<0)
{
rank++;
num=limit(rank)-1;
}
}
if(!rank)break;
}
if(!rank) cout<<"Legend"<<endl;
else cout<<rank<<endl;
}
return 0;
}
B - Where is the Marble?
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1415
题意不难理解。思路上直接使用sort进行排序后使用lower_bound进行搜索,如存在则与搜索结果相等,如不存在则返回一个大于搜索值的结果。
lower_bound(数据始,数据末,待搜索值)
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
int arr[100005];
int main()
{
int n,q;
int cnt=0;
while(cin>>n>>q&&n!=0)
{
for(int i=0;i<n;i++)
cin>>arr[i];
sort(arr,arr+n);
int num[10005];
for(int i=0;i<q;i++)
{
cin>>num[i];
}
cout<<"CASE# "<<++cnt<<":"<<endl;
for(int i=0;i<q;i++)
{
int *q=lower_bound(arr,arr+n,num[i]);
if(*q==num[i])
{
cout<<num[i]<<" found at "<<q-arr+1<<endl;
}
else cout<<num[i]<<" not found"<<endl;
}
}
return 0;
}
C - Bit String Reordering
http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2089
Description
You have to reorder a given bit string as specified. The only operation allowed is swapping adjacent bit pairs. Please write a program that calculates the minimum number of swaps required. The initial bit string is simply represented by a sequence of bits, while the target is specified by a run-length code. The run-length code of a bit string is a sequence of the lengths of maximal consecutive sequences of zeros or ones in the bit string. For example, the run-length code of “011100” is “1 3 2”. Note that there are two different bit strings with the same run-length code, one starting with zero and the other starting with one. The target is either of these two. In Sample Input 1, bit string “100101” should be reordered so that its run-length code is “1 3 2”, which means either “100011” or “011100”. At least four swaps are required to obtain “011100”. On the other hand, only one swap is required to make “100011”. Thus, in this example, 1 is the answer.
Input
The input consists of several tests case. For each test, the test case is formatted as follows. NM b1 b2 ...bN p1 p2 ...pM ThefirstlinecontainstwointegersN (1≤N ≤15)andM (1≤M ≤N). Thesecondline specifies the initial bit string by N integers. Each integer bi is either 0 or 1. The third line contains the run-length code, consisting of M integers. Integers p1 through pM represent the lengths of consecutive sequences of zeros or ones in the bit string, from left to right. Here, 1≤pj for1≤j≤M and Mj=1pj =N hold. Itisguaranteedthattheinitialbitstringcanbe reordered into a bit string with its run-length code p1, . . . , pM .
Output
Output the minimum number of swaps required.
Sample Input
6 3
1 0 0 1 0 1
1 3 2
7 2
1 1 1 0 0 0 0
4 3
15 14
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 2
1 1
0
1
Sample Output
1
12
7
0
Hint
Source
Asia Regional Contest, Tokyo, 2014
简单题,直接暴力
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
const int INF=0x3f3f3f3f;
void pre_solve(int *ori,int tar1[],int tar2[],int len)
{
int i;
int cnt=0;
int flag=0;
for(i=0;i<len;i++)
{
for(int j=0;j<ori[i];j++)
{
tar1[cnt]=flag;
tar2[cnt++]=1-flag;
}
flag=1-flag;
}
}
int compare(int a[],int b[],int len)
{
int i=0;int ans=0;
for(i=0;i<len;i++)
{
if(a[i]!=b[i])
{
//cout<<i<<endl;
int j=i;//if(j==len-1) return INF;
for(;a[j]!=b[i];j++,ans++)
{
//cout<<j<<endl;
if(j==len-1) return INF;
}
swap(a[i],a[j]);
}
}
//cout<<ans<<endl;
return ans;
}
int main()
{
int arr[20],obj[20],arr2[20];
int tar1[20],tar2[20];
int n,m;
while(cin>>n>>m)
{
int i;
for(i=0;i<n;i++)
{
cin>>arr[i];
arr2[i]=arr[i];
}
for(i=0;i<m;i++)
{
cin>>obj[i];
}
pre_solve(obj,tar1,tar2,m);
/*for(i=0;i<n;i++)
{
cout<<tar2[i]<<' ';
} */
int ans=min(compare(arr,tar1,n),compare(arr2,tar2,n));
cout<<ans<<endl;
}
return 0;
}
D - The Blocks Problem
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=37
Background
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
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 b i adjacent to block b i+1 for all as shown in the diagram below:
Figure: Initial Blocks World
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.
The 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.
The Output
The output should consist of the final state of the blocks world. Each original block position numbered i ( 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:
题目大意:
1,move onto将a,b上的积木清空,然后将a放在b上。
2,move over将a上的积木清空,然后将a放在b的最上方。
3,pile onto 将b上的积木清空,然后将a和a上的积木放在b上。
4,pile over将a和上的积木放在b的随上方。
(a,b同属于一个木块堆时为错误操作,跳过)
代码与思路均来自紫书,原代码极具美感。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
const int maxn=30;
vector<int>l[maxn];
int n;
void found(int a, int &p, int &h)
{
for (p = 0; p < n; p++)
for (h = 0; h < l[p].size(); h++)
{
if (l[p][h] == a) return;
}
}
void go_back(int p,int h)
{
for (int i = h + 1; i < l[p].size(); i++)
{
int b = l[p][i];
l[b].push_back(b);
}
l[p].resize(h + 1);
}
void pile_onto(int p, int h, int p2)
{
for (int i = h; i < l[p].size(); i++)
l[p2].push_back(l[p][i]);
l[p].resize(h);
}
void print()
{
for(int i=0;i<n;i++)
{
cout<<i<<":";
for(int q=0;q<l[i].size();q++)
{
cout<<" "<<l[i][q];
}
cout<<endl;
}
}
int main()
{
int a,b;
string x,y;
cin>>n;
for(int i=0;i<n;i++) l[i].push_back(i);
while(cin>>x)
{
if(x=="quit")break;
cin>>a>>y>>b;
int pa,pb,ha,hb;
found(a,pa,ha);
found(b,pb,hb);
if(pa==pb) continue;
if(y=="onto") go_back(pb,hb);
if(x=="move") go_back(pa,ha);
pile_onto(pa, ha, pb);
}
print();
return 0;
}
E - Ugly Numbers
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=72
Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, ...
shows the first 11 ugly numbers. By convention, 1 is included.
Write a program to find and print the 1500'th ugly number.
Input and Output
There is no input to this program. Output should consist of a single line as shown below, with <number> replaced by the number computed.
Sample output
The 1500'th ugly number is <number>.
本题极简单,直接对1乘上i个2,j个3,k个5,然后对i,j,k从1到20遍历,存入一数组然后sort或者nth_element求出。数是859963392
代码就不贴了。
F - Misha and Changing Handles
Misha hacked the Codeforces site. Then he decided to let all the users change their handles. A user can now change his handle any number of times. But each new handle must not be equal to any handle that is already used or that was used at some point.
Misha has a list of handle change requests. After completing the requests he wants to understand the relation between the original and the new handles of the users. Help him to do that.
Input
The first line contains integer q (1 ≤ q ≤ 1000), the number of handle change requests.
Next q lines contain the descriptions of the requests, one per line.
Each query consists of two non-empty strings old and new, separated by a space. The strings consist of lowercase and uppercase Latin letters and digits. Strings old and new are distinct. The lengths of the strings do not exceed 20.
The requests are given chronologically. In other words, by the moment of a query there is a single person with handle old, and handle new is not used and has not been used by anyone.
Output
In the first line output the integer n — the number of users that changed their handles at least once.
In the next n lines print the mapping between the old and the new handles of the users. Each of them must contain two strings, old and new, separated by a space, meaning that before the user had handle old, and after all the requests are completed, his handle is new. You may output lines in any order.
Each user who changes the handle must occur exactly once in this description.
Examples
Input
5
Misha ILoveCodeforces
Vasya Petrov
Petrov VasyaPetrov123
ILoveCodeforces MikeMirzayanov
Petya Ivanov
Output
3
Petya Ivanov
Misha MikeMirzayanov
Vasya VasyaPetrov123
本题就是链接首末的拓扑关系,使用map,为了方便查找与删除选择以后一项为first前一项为second
代码如下:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
map<string,string> m;
int main()
{
int n;
while(cin>>n)
{
for(int i=0;i<n;i++)
{
string a,b;
cin>>a>>b;
m[b]=a;
if(m.count(a)!=0)
{
m[b]=m[a];
m.erase(a);
}
}
cout<<m.size()<<endl;
for(auto i=m.begin();i!=m.end();i++)
{
cout<<i->second<<' '<<i->first<<endl;
}
}
return 0;
}
G - Ignatius and the Princess II
http://acm.hdu.edu.cn/showproblem.php?pid=1027
Now our hero finds the door to the BEelzebub feng5166. He opens the door and finds feng5166 is about to kill our pretty Princess. But now the BEelzebub has to beat our hero first. feng5166 says, "I have three question for you, if you can work them out, I will release the Princess, or you will be my dinner, too." Ignatius says confidently, "OK, at last, I will save the Princess."
"Now I will show you the first problem." feng5166 says, "Given a sequence of number 1 to N, we define that 1,2,3...N-1,N is the smallest sequence among all the sequence which can be composed with number 1 to N(each number can be and should be use only once in this problem). So it's easy to see the second smallest sequence is 1,2,3...N,N-1. Now I will give you two numbers, N and M. You should tell me the Mth smallest sequence which is composed with number 1 to N. It's easy, isn't is? Hahahahaha......"
Can you help Ignatius to solve this problem?
Input
The input contains several test cases. Each test case consists of two numbers, N and M(1<=N<=1000, 1<=M<=10000). You may assume that there is always a sequence satisfied the BEelzebub's demand. The input is terminated by the end of file.
Output
For each test case, you only have to output the sequence satisfied the BEelzebub's demand. When output a sequence, you should print a space between two numbers, but do not output any spaces after the last number.
Sample Input
6 4
11 8
Sample Output
1 2 3 5 6 4
1 2 3 4 5 6 7 9 8 11 10
本题使用next_permutation(begin,end);函数
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
int arr[1005];
void init(int x)
{
memset(arr,0,sizeof(arr));
for(int i=1;i<=x;i++)
{
arr[i]=i;
}
}
int main()
{
int n,m;
while(cin>>n>>m)
{
init(n);
for(int i=0;i<m-1;i++)
next_permutation(arr+1,arr+1+n);
for(int i=1;i<=n;i++)
{
cout<<arr[i];
if(i!=n)cout<<' ';
else cout<<'\n';
}
}
return 0;
}
H - Compound Words
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1332
You are to find all the two-word compound words in a dictionary. A two-word compound word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.
Input
Standard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 120,000 words.
Output
Your output should contain all the compound words, one per line, in alphabetical order.
Sample Input
a
alien
born
less
lien
never
nevertheless
new
newborn
the
zebra
Sample Output
alien
newborn
本题使用了set的count成员函数,与string的substr函数暴力破解
str.substr(begin,length),length可以缺省,如缺省则截至末尾
代码如下:
#include<set>
#include<string>
#include<iostream>
using namespace std;
set<string> s;
int main()
{
string str;
while(cin>>str)
{
s.insert(str);
}
for(auto it=s.begin();it!=s.end();it++)
{
for(int i=1;i<(*it).length();i++)
{
string fro=(*it).substr(0,i);
string las=(*it).substr(i);
if(s.count(fro)&&s.count(las))
{
cout<<(*it)<<endl;
break;
}
}
}
}
代码如下