UPC 2020秋组队真题训练赛第八场【A&B&C&D&G】

问题 A:Alphabet Animals

题目描述
You are playing a game in which a group of players take turns saying animal names. The animal name you say when it is your turn must start with the same letter as the previously said animal ends with and it must not have been said previously in this round of the game. If there is no valid name or you cannot come up with one you are eliminated.
Given the last animal name said before your turn and a list of all names not yet used, can you make it through this turn? If so, can you make sure to eliminate the next player?

输入
The first line of input contains a single word, the animal that the previous player just said. The next line contains a single integer n (0 ≤ n ≤ 10^5 ), the number of valid unused animal names.
Each of the following n lines contains one valid unused animal name.
All animal names (including the one the previous player said) are unique and consist of at least 1 and at most 20 lower case letters ‘ a ’-‘ z ’.

输出
If there is any animal name you can play that eliminates the next player, output the first such name from the input list, followed by an exclamation mark. Otherwise, if there is any animal name that you can play, output the first such name. Otherwise, output a question mark (in this case you will just have to make up a fake name in the hope that the others will trust you that this is a real animal).

样例输入
pig
2
goat
toad
样例输出
goat

词语接龙。分类讨论即可。开一个大小为26的cnt数组统计以xx为首字母的单词有几个。

// A.
#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int N=1e6;
string k;
int n,i,vis[26]={
    
    0};

int main()
{
    
    
    vector<string>v;
    cin>>k>>n;
    
    for(i=0; i<=n-1; i++)
    {
    
    
        string t;
        cin>>t;
        v.push_back(t);
        vis[v[i][0]-'a']++;
    }
    
    bool flag=0;
    string bb="";
    
    for(i=0; i<=n-1; i++)
    {
    
    
        if(v[i][0]==k[k.size()-1])
        {
    
    
            flag=1;
            char t=v[i][v[i].size()-1];
            vis[v[i][0]-'a']--;
            
            if(bb=="")  bb=v[i];
            
            if(vis[t-'a']==0)
            {
    
    
                cout<<v[i]<<"!";
                return 0;
            }
            
            vis[v[i][0]-'a']++;
        }
    }
    
    if(!flag)    cout<<"?";
    else    cout<<bb;
    return 0;
}

问题 B:Building Boundaries

题目描述
Maarja wants to buy a rectangular piece of land and then construct three buildings on that land.
The boundaries of the buildings on the ground must have rectangular sizes a1 × b1 , a2 × b2 ,and a3 × b3 . They can touch each other but they may not overlap. They can also be rotated as long as their sides are horizontal and vertical.
What is the minimum area of land Maarja has to buy?
在这里插入图片描述

Figure B.1: Illustration of the two test scenarios in Sample Input 1 and their solutions. In the second scenario the 5 × 1 building has been rotated by 90 degrees.

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

输入
The input consists of multiple test scenarios. The first line of input contains a single integer t(1 ≤ t ≤ 1000), the number of scenarios. Then follow the t scenarios. Each scenario consists of a single line, containing six integers a1 , b1 , a2 , b2 , a3 and b3 (1 ≤ a1 , b1 , a2 , b2 , a3 , b3 ≤ 10^9 ).

输出
For each test scenario, output the minimum area of land such that Maarja can construct the three buildings.

样例输入
2
2 3 2 2 1 1
2 4 5 1 2 3
样例输出
12
21
在这里插入图片描述

思路:先给出一个放置3个矩形的方式【这样不会漏情况,不能只想着特殊情况去特判拿分,非oi赛制…要先考虑一般情况。】:任意放一个矩形,把第二个矩形贴着第一个的右边(保证上方平行),第三个有3种放法。接着要考虑三个矩形哪一个放在第一块、第二块…(用组合数学的知识可以得到有6种情况)和每一个矩形是用长还是宽去贴(也就是每个矩形有两种旋转姿势,共2^3种情况)。所以共有48中情况需要遍历,每次输入进行48次遍历取最优即可。

// B.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = 0x3f3f3f3f3f3f3f3f;
 
struct node {
    
    ll x, y;} s[3][2]; //用一个结构体去存储长和宽
 
int main()
{
    
    
    int t;  cin>>t;
    
    while(t--) //多组数据控制
    {
    
    
        for(int i=0; i<3; i++) 
        {
    
    
            scanf("%lld%lld", &s[i][0].x, &s[i][0].y);
            s[i][1].x = s[i][0].y;
            s[i][1].y = s[i][0].x;
        }
        ll minn = inf;
        
        for(int i=0; i<3; i++)
          for(int j=i+1; j<3; j++)
          {
    
    
            int k;
            for(int p=0; p<3; p++)
                if(i!=p && j!=p)  {
    
    k=p;  break;}
                
            for(int o=0; o<2; o++)
              for(int p=0; p<2; p++)
                for(int q=0; q<2; q++)
                {
    
    
                    minn = min(minn, max(s[k][q].x, (s[i][o].x + s[j][p].x)) * (max(s[i][o].y, s[j][p].y) + s[k][q].y));
                    minn = min(minn, (s[i][o].x + max(s[j][p].x, s[k][q].x)) * max(s[i][o].y, s[j][p].y + s[k][q].y));
                    minn = min(minn, (s[i][o].x + s[j][p].x + s[k][q].x) * max(s[i][o].y, max(s[j][p].y, s[k][q].y)));
                }
          }
        
        cout<<minn<<endl;
    }
    return 0;
}

问题 C:Cocoa Coalition

题目描述
Alice and Bob decide to share a chocolate bar, which is an n by m rectangular grid of chocolate cells. They decide that Alice should get a < n·m pieces and that Bob should get b = n·m − a pieces. To split the chocolate bar, they repeatedly take a single piece of chocolate and break it either horizontally or vertically, creating two smaller pieces of chocolate. See Figure C.1 for an example.
What is the minimum number of splits that Alice and Bob need to perform in order to split the n-by-m chocolate bar into two piles consisting of a and b chocolate cells?
在这里插入图片描述
Figure C.1: Illustration of a solution to Sample Input 2, showing the original 10-by-10 chocolate bar split three times into pieces of size 10-by-2, 10-by-5, 3-by-3 and 7-by-3. Giving Alice the 10-by-5 and 7-by-3 pieces, she gets a total of 50 + 21 = 71 chocolate cells.

输入
The input consists of a single line, containing the three integers n, m and a (1 ≤ n, m ≤ 10^6 ,1 ≤ a < n · m).

输出
Output the minimum number of splits needed to achieve the desired division of chocolate.

样例输入
3 10 9
样例输出
1

题意: 在 n * m 块巧克力中切出 a 块巧克力,只能横着切或竖着切,问最少切几刀。

思路: 最多切三次。一般需要一次两次或三次,除去一次两次的就是三次。

具体思路:

(1)若 a % n == 0 || a % m == 0,一刀即可

(2)若 a 可以分解为两正数之积,且这两个数一个小于 n 并且一个小于 m ,切2刀

(3)其余情况都是3刀

注意: 不一定是小块好切(比如 n = 4, m = 10, a = 13, 答案是切出27块来,切两刀),因此 a 和 n * m - a 要比较一下

// C.
#include <bits/stdc++.h>
#define ll long long 
using namespace std;
ll n,m,a;

ll so(ll a)
{
    
    
    ll ans;
    if(a%n==0 || a%m==0)   ans=1;
    
    else {
    
    
        bool f=0;
        for(ll i=1; i<=sqrt(a); i++) {
    
    
            if(a%i==0) {
    
    
                if(a/i<n && i<m)  {
    
    f=1; break;}
                if(a/i<m && i<n)  {
    
    f=1; break;}
            }
        }
        if(f)   ans=2;
        else   ans=3;
    }
    return ans;
}
 
int main() {
    
    
    while(~scanf("%lld %lld %lld",&n,&m,&a)) {
    
    
        cout<<min(so(a),so(n*m-a))<<endl;
    }
    return 0;
}

问题 D:Eeny Meeny

题目描述
“Eeny meeny miny moe” is a well-known nursery rhyme in English, used (among other things) by kids to “randomly” select members of a team. It exists in many variations, one of which goes like this:
Eeny, meeny, miny, moe,
Catch a tiger by the toe.
If he hollers, let him go,
Eeny, meeny, miny, moe.
Similar verses exist in most languages, such as “Ulle dulle dof” in finnish, “Akka bakka bonka rakka” in Norwegian, and “Ole dole doff” in Swedish.
Two teams are to be selected for a game and the rhyme is used to select one kid for a team at a time, alternating between the two teams, until all kids have been selected. The kids are standing in a circle. In each selection round we start counting the kids in clockwise order around the circle, skipping one kid for every word in the rhyme, until the last word. The kid matching the last word is chosen for the current team and then the next round starts. In all rounds but the first, the counting starts at the next remaining kid (in clockwise order) after the one that was selected in the previous round. See figure E.1 for an example.
Given such a rhyme, and a group of kids, can you tell which kids will be in which team?
在这里插入图片描述
figure E.1: Illustration of the first three rounds of Sample Input 1. In rounds 1 and 3, Alvar and Rakel get selected for the first team, and in round 2, Lisa is selected for the second team. In round 4 (not shown), only Kalle remains and is selected for the second team.
输入
The first line of input contains the rhyme, consisting of a list of words separated by spaces. The second line of input contains an integer n (1 ≤ n ≤ 100), the number of kids. Then follow the names of the kids, one per line. The kids are given in clockwise order and the first kid listed is the one at which counting starts in the first round.
All words and names consist only of upper and lower case letters ‘ A ’-‘ Z ’ and ‘ a ’-‘ z ’. No input line is empty or longer than 100 characters (excluding the newline character at the end of the line).

输出
Output the two teams, starting with the one whose first member is chosen first. For each team, output the number of kids in the team, followed by the names of the kids in the team, in the same order as they were chosen for the team.

样例输入
eeny meeny miny
4
Kalle
Lisa
Alvar
Rakel
样例输出
2
Alvar
Rakel
2
Lisa
Kalle

思路:有点类似约瑟夫环的意思,队列模拟即可。

// D.
#include <bits/stdc++.h>
using namespace std;
string s;
vector<string>v1,v2;
queue<string>q;
int n;

int main()
{
    
    
    getline(cin,s);
    cin>>n;
    int i,len=0;
    for(i=0; i<s.size(); i++)
        if(s[i]==' ')  len++;
    
    len++;
    for(i=1; i<=n; i++)
    {
    
    
        string t;
        cin>>t;
        q.push(t);
    }
    int cnt=1;
    
    while(q.size())
    {
    
    
        int i;
        for(i=1; i<=len; i++)
        {
    
    
            string t=q.front();
            q.pop();
            if(i!=len)   q.push(t);
            
            else
            {
    
    
                if(cnt&1)v1.push_back(t);
                else v2.push_back(t);
            }
        }
        cnt++;
    }
    cout << v1.size() << endl;
    
    for(i=0; i<v1.size(); i++)
        cout << v1[i] << endl;
    
    cout << v2.size() << endl;
    
    for(i=0; i<v2.size(); i++) 
	    cout << v2[i] << endl;
}

问题 G:Hot Hike

题目描述
In order to pass time during your vacation, you decided to go on a hike to visit a scenic lake up in the mountains. Hiking to the lake will take you a full day, then you will stay there for a day to rest and enjoy the scenery, and then spend another day hiking home, for a total of three days. However, the accursed weather this summer is ridiculously warm and sunny, and since severe dehydration is not at the top of your priority list you want to schedule the three-day trip during some days where the two hiking days are the least warm. In particular you want to minimize the maximum temperature during the two hiking days.
Given the current forecast of daily maximum temperatures during your vacation, what are the best days for your trip?

输入
The first line of input contains an integer n (3 ≤ n ≤ 50), the length of your vacation in days. Then follows a line containing n integers t1 , t2 , . . . , tn (−20 ≤ t i ≤ 40), where ti is the temperature forecast for the i’th day of your vacation.

输出
Output two integers d and t, where d is the best day to start your trip, and t is the resulting maximum temperature during the two hiking days. If there are many choices of d that minimize the value of t, then output the smallest such d.

样例输入
5
23 27 31 28 30
样例输出
2 28

思路:模拟签到,三天一组,求最大温度及其对应的天数、

// G.
#include<bits/stdc++.h>
using namespace std;
int a[55],t=0,tem=10000,s=0;

int main()
{
    
    
	int n;	cin>>n;
	for(int i=1; i<=n; i++)	cin>>a[i];
	
	for(int i=1; i<=n-2; i++)
	{
    
    
	    t=max(a[i],a[i+2]);
	    if(t<tem)
	    {
    
    
		    tem=t;
		    s=i;
	    }
	}
	cout<<s<<" "<<tem<<endl;
}

猜你喜欢

转载自blog.csdn.net/Luoxiaobaia/article/details/108565905
UPC