SDUT 2020 Autumn Team Contest---26(for 19.div2) 部分题解

48 篇文章 0 订阅

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?

Input
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≤105), 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’.

Output
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).

思路:直接模拟

Sample Input 1

pig
2
goat
toad

Sample Output 1

goat

Sample Input 2

dog
2
snake
emu

Sample Output 2

?

Sample Input 3

hare
3
bee
cat
eagle

Sample Output 3

eagle!

答案:

#include <iostream>
#include<bits/stdc++.h>
#define ll long long
const int N = 1e5 + 10;
using namespace std;
char s[10009];
char k[100009][29];
int cnt[29],head[29],lenk[100009];
int main()
{
    ios::sync_with_stdio(0);
    int n;
    scanf("%s",s);
    int len = strlen(s);
    int now = s[len-1]-'a';
    scanf("%d",&n);
    for(int i=1; i<=n; ++i)
    {
        scanf("%s",k[i]);
        lenk[i] = strlen(k[i]);
        cnt[k[i][lenk[i]-1]-'a']++;
        head[k[i][0]-'a']++;
    }
    int flag = -1,id;
    for(int i=1; i<=n; ++i)
    {
        int h = k[i][0]-'a',t = k[i][lenk[i]-1]-'a';
        if(h==now&&(head[t]==0||(head[t]==1&&h==t)))
        {
            flag = 1;
            id = i;
            break;
        }
        else if(h==now&&flag==-1)
        {
            flag = 0;
            id = i;
        }
    }
    if(flag==1)
    {
        printf("%s!\n",k[id]);
    }
    else if(flag==0)
    {
        puts(k[id]);
    }
    else
        puts("?");
    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?

\includegraphics[width=0.6\textwidth ]{samples}

Figure 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.

Input
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≤109).

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

题目大意:
分别给出三个矩形的长和宽,求一个最小的矩形能够把三个矩形都放进去,且放进去的三个矩形之间不发生重叠。

解题思路:
逐一枚举三个矩形组合的所有方案,算出每个组合方案的矩形面积,并取一个最小值。
组合情况,可大致分为以下两种:

1、三个矩形各有一条边在同一直线上,如下图:
在这里插入图片描述

2、两个矩形各有一条边在同一直线上,如下图:
在这里插入图片描述

按照每种情况各自的组合方式,列出所有的方案即可,代码也比较有条理,而且还很清晰

Sample Input 1

2
2 3 2 2 1 1
2 4 5 1 2 3

Sample Output 1

12
21

答案:

#include <iostream>
#include<bits/stdc++.h>
#define ll long long
const int N = 1e5 + 10;
using namespace std;
ll a[9],b[9];
int main()
{
    int t ;
    scanf("%d",&t);
    while(t--)
    {
        for(int i=1; i<=3; ++i)
            scanf("%lld%lld",&a[i],&b[i]);
        ll mx ;
        for(int i=1; i<=2; ++i)
        {
            for(int j=1; j<=2; ++j)
            {
                for(int p=1; p<=2; ++p)
                {
                    ll l = 0,r = 0;
                    l+=a[1]+a[2]+a[3];
                    r = max(b[1],b[2]);
                    r = max(b[3],r);
                    if(i==1&&j==1&&p==1)
                    {
                        mx = l*r;
                    }
                    else
                    {
                        mx = min(mx,l*r);
                    }
                    swap(a[3],b[3]);
                }
                swap(a[2],b[2]);
            }
            swap(a[1],b[1]);
        }
        for(int i=1; i<=3; ++i)
        {
            for(int j=1; j<=2; ++j)
            {
                for(int p=1; p<=2; ++p)
                {
                    for(int k=1; k<=2; ++k)
                    {
                        ll l = max(a[1]+a[2],a[3]);
                        ll r = b[3]+max(b[1],b[2]);
                        mx = min(l*r,mx);
                        swap(a[3],b[3]);
                    }
                    swap(a[2],b[2]);
                }
                swap(a[1],b[1]);
            }
            swap(a[i],a[3]);
            swap(b[i],b[3]);
        }
        printf("%lld\n",mx);
    }
    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 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?

\includegraphics[width=0.4\textwidth ]{sample2}

Figure 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.

Input
The input consists of a single line, containing the three integers n, m and a (1≤n,m≤106, 1≤a<n⋅m).

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

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

Sample Input 1

3 10 9

Sample Output 1

1

Sample Input 2

10 10 71

Sample Output 2

3

答案:

#include <iostream>
#include<bits/stdc++.h>
#define ll long long
const int N = 1e5 + 10;
using namespace std;
ll n,m,a;
int main()
{
    scanf("%lld%lld%lld",&n,&m,&a);
    ll k = n*m;
    if(a%m==0||a%n==0)
    {
        puts("1");
        return 0;
    }
    k-=a;
    k = min(k,a);
    if(k<max(n,m))
    {
        puts("2");
    }
    else
    {
        int cnt = 0;
        while(cnt<2)
        {
            if(cnt==1)
                a = n*m-a;
            cnt++;
            ll h = a%m, c = a%n;
            ll v = n-a/m,v1 = m-a/n;
            if(h%v==0||c%v1==0)
            {
                puts("2");
                return 0;
            }
            else
            {
                for(ll i=2; i<=sqrt(a); ++i)
                {
                    if(a%i==0)
                    {
                        ll cur = a/i;
                        if(cur<=max(m,n)&&i<=min(m,n))
                        {
                            puts("2");
                            return 0;
                        }
                    }
                }
            }
        }
        puts("3");
    }
    return 0;
}

E - 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 1 for an example.

Given such a rhyme, and a group of kids, can you tell which kids will be in which team?

\includegraphics[width=0.99\textwidth ]{sample1}

Figure 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.

Input
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
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.

思路:约瑟夫环

Sample Input 1

eeny meeny miny
4
Kalle
Lisa
Alvar
Rakel

Sample Output 1

2
Alvar
Rakel
2
Lisa
Kalle

Sample Input 2

Every Other
3
a
b
c

Sample Output 2

2
b
c
1
a

答案:

#include <iostream>
#include<bits/stdc++.h>
#define ll long long
const int N = 1e5 + 10;
using namespace std;
ll n,m,a;
int main()
{
    scanf("%lld%lld%lld",&n,&m,&a);
    ll k = n*m;
    if(a%m==0||a%n==0)
    {
        puts("1");
        return 0;
    }
    k-=a;
    k = min(k,a);
    if(k<max(n,m))
    {
        puts("2");
    }
    else
    {
        int cnt = 0;
        while(cnt<2)
        {
            if(cnt==1)
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
                const int N = 1e5 + 10;
            using namespace std;
            int cnt = 1;
            char st;
            struct node
            {
                char name[109];
                node*next;
            };
            char s[3][109][111];
            int main()
            {
                while(1)
                {
                    scanf("%c",&st);
                    if(st==' ')
                        cnt++;
                    if(st=='\n')
                        break;
                }
                int n;
                scanf("%d",&n);
                node * head  = new node;
                node * p = head;
                p->next = NULL;
                for(int i=1; i<=n; ++i)
                {
                    node *t = new node;
                    scanf("%s",t->name);
                    p->next = t;
                    p=p->next;
                    p->next = NULL;
                }
                //printf("%s\n",p->name);
                p->next = head->next;
                node *pr=p;
                p=p->next;
                int now = 1,pop[3]= {0};
                while(n)
                {
                    for(int i=1; i<cnt; ++i)
                    {
                        p=p->next;
                        pr=pr->next;
                    }
                    strcpy(s[now][++pop[now]],p->name);
                    pr->next = p->next;
                    p=p->next;
                    now++;
                    if(now>2)
                        now = 1;
                    n--;
                }
                for(int i=1; i<=2; ++i)
                {
                    printf("%d\n",pop[i]);
                    for(int j=1; j<=pop[i]; ++j)
                    {
                        puts(s[i][j]);
                    }
                }
                return 0;
            }
            a = n*m-a;
            cnt++;
            ll h = a%m, c = a%n;
            ll v = n-a/m,v1 = m-a/n;
            if(h%v==0||c%v1==0)
            {
                puts("2");
                return 0;
            }
            else
            {
                for(ll i=2; i<=sqrt(a); ++i)
                {
                    if(a%i==0)
                    {
                        ll cur = a/i;
                        if(cur<=max(m,n)&&i<=min(m,n))
                        {
                            puts("2");
                            return 0;
                        }
                    }
                }
            }
        }
        puts("3");
    }
    return 0;
}

H - 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?

Input
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≤ti≤40), where ti is the temperature forecast for the i’th day of your vacation.

Output
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.

Sample Input 1

5
23 27 31 28 30

Sample Output 1

2 28

Sample Input 2

4
30 20 20 30

Sample Output 2

1 30

答案:

#include <iostream>
#include<bits/stdc++.h>
#define ll long long
const int N = 1e5 + 10;
using namespace std;
int a[10009];
int main()
{
    ios::sync_with_stdio(0);
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; ++i)
    {
        scanf("%d",&a[i]);
    }
    int sum, id=1;
    for(int i=1; i<=n-2; ++i)
    {
        if(i==1)
        {
            sum = max(a[1],a[3]);
        }
        else
        {
            int x= max(a[i],a[i+2]);
            if(sum>x)
            {
                id = i;
                sum = x;
            }
        }
    }
    printf("%d %d\n",id,sum);
    return 0;
}

K - Keep it Cool

As the workload of the semester is ramping up you get the task of refilling the fridge in the lab with soda. The fridge has s slots, each with a capacity for d bottles of soda, and you have n new soda bottles to add to the fridge. The sodas currently in the fridge are all nice and cold, but the new ones are not and need to be cooled in the fridge for a while until they are ready to drink.
You can only refill the fridge from the front, so in an ideal world, you would first take out all the sodas currently in the fridge, then put in the n new ones, and then put the old and cold sodas in front of the new ones. But in an ideal world you would also not have two exams and a homework deadline coming. You are simply way too busy to do all this work.

Instead, you are going to just put the new bottles in the front of the fridge and hope for the best. However, you can still to be clever about which slots to put the new sodas in. Each time a student comes for a soda, they will take one from the front of a uniformly random non-empty slot in the fridge. You decide to add the new bottles to the fridge so as to maximize the probability that all the next m students getting a soda from the fridge will get a cold one.

Input
The first line of input contains four integers n, m, s and d (1≤n,m,s,d≤100), the number of new soda bottles, number of students to optimize for, number of slots in the fridge, and capacity of each slot, respectively. Then follows a line containing s integers c1,…,cs (0≤ci≤d for each i), where ci is the number of soda bottles currently in slot i of the fridge.

You may assume that there is free space for all the n new bottles in the fridge.

Output
If there is a chance that all the next m students will get a cold bottle, then output s integers describing a refill scheme for the n soda bottles that maximizes the probability of this happening. The ith of these s integers indicates how many of the new bottles are placed in the front of slot i in the fridge. If there are multiple optimal refill schemes, output any one of them. Otherwise, if it is impossible for all the next m students to get a cold soda, output “impossible” instead.

思路:贪心,尽可能把的往冰水少的地方放满即可

Sample Input 1

5 3 3 4
0 1 4

Sample Output 1

2 3 0

Sample Input 2

2 7 6 4
0 1 2 2 0 1

Sample Output 2

impossible

答案:

#include <iostream>
#include<bits/stdc++.h>
#define ll long long
const int N = 1e5 + 10;
using namespace std;
int n,m,s,d,c[109];
struct node
{
    int id,b;
};
node now[109];
int cmp(const node&a,const node&b)
{
    return a.b<b.b;
}
int ans[109];
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&d);
    int sum = 0;
    for(int i=1; i<=s; ++i)
    {
        scanf("%d",&c[i]);
        now[i].b = c[i];
        sum+=c[i];
        now[i].id = i;
    }
    if(sum<m)
        puts("impossible");
    else
    {
        int i;
        sort(now+1,now+1+s,cmp);
        int cur = n;
        int k = n;
        for(i=1; i<=s; ++i)
        {
            cur-=d-now[i].b;
            ans[now[i].id] = min(k,d-now[i].b);
            k-=ans[now[i].id];
            if(k==0)
                break;
            if(cur<=0)
                break;
        }
        if(i==s||i==s+1)
            puts("impossible");
        else
        {
            int sumx = 0;
            for(int j=i+1; j<=s; ++j)
            {
                sumx+=now[j].b;
            }
            if(sumx>=m)
            {
                for(int j=1; j<=s; ++j)
                    printf("%d%c",ans[j],j==s?'\n':' ');
            }
            else
                puts("impossible");
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值