2021UPC第十四场部分题解(ADFL)

2021UPC第十四场部分题解(ADFL)


前言

这一次还是好多都不会,还是我太菜了


A 火星人问题

火星人用一种非常简单的方式来表示数字――掰手指。火星人只有一只手,但这只手上有成千上万的手指,这些手指排成一列,分别编号为1,2,3……。火星人的任意两根手指都能随意交换位置,他们就是通过这方法计数的。一个火星人用一个人类的手演示了如何用手指计数。如果把五根手指――拇指、食指、中指、无名指和小指分别编号为1,2,3,4和5,当它们按正常顺序排列时,形成了5位数12345,当你交换无名指和小指的位置时,会形成5位数12354,当你把五个手指的顺序完全颠倒时,会形成54321,在所有能够形成的120个5位数中,12345最小,它表示1;12354第二小,它表示2;54321最大,它表示120。下表展示了只有3根手指时能够形成的6个3位数和它们代表的数字:
三进制数
123 132 213 231 312 321

代表的数字
1 2 3 4 5 6

现在你有幸成为了第一个和火星人交流的地球人。一个火星人会让你看他的手指,科学家会告诉你要加上去的很小的数。你的任务是,把火星人用手指表示的数与科学家告诉你的数相加,并根据相加的结果改变火星人手指的排列顺序。输入数据保证这个结果不会超出火星人手指能表示的范围。
输入
5
3
1 2 3 4 5
输出
1 2 4 5 3
思路:看着题的意思就是给一组数,求比它大m的排列,那就套stl中的next_permutation喽
代码如下

#include<bits/stdc++.h>

using namespace std;
int a[10008];
int main()
{
    int n,m;
    cin >> n >> m;
    for(int i=1;i<=n;i++)
        cin >> a[i];
    for(int i=1;i<=m;i++)
    {
         next_permutation(a+1,a+n+1);  
    }
    for(int i=1;i<=n;i++)
    {
         cout << a[i] << " ";  
    }
    return 0;
}

F: Card Game for Three

Alice, Bob and Charlie are playing Card Game for Three, as below:

At first, each of the three players has a deck consisting of some number of cards. Each card has a letter a, b or c written on it. The orders of the cards in the decks cannot be rearranged.
The players take turns. Alice goes first.
If the current player’s deck contains at least one card, discard the top card in the deck. Then, the player whose name begins with the letter on the discarded card, takes the next turn. (For example, if the card says a, Alice takes the next turn.)
If the current player’s deck is empty, the game ends and the current player wins the game.
You are given the initial decks of the players. More specifically, you are given three strings SA, SB and SC. The i-th (1≦i≦|SA|) letter in SA is the letter on the i-th card in Alice’s initial deck. SB and SC describes Bob’s and Charlie’s initial decks in the same way.

Determine the winner of the game.

Constraints
1≦|SA|≦100
1≦|SB|≦100
1≦|SC|≦100
Each letter in SA, SB, SC is a, b or c.
输入
The input is given from Standard Input in the following format:
SA
SB
SC
输出
If Alice will win, print A. If Bob will win, print B. If Charlie will win, print C.
样例输入 Copy
aca
accc
ca
样例输出 Copy
A
题意:就是abc三个人都有一副只有abc的牌,第一轮a先抽,抽到谁轮到谁抽,直到一个人才轮到他他的牌空为止
思路:是不是很容易想到stl的队列,因为只涉及到队首的操作,建立三个队列,之后模拟,轮到谁就让谁的队列的队首出队,注意判空即可

#include<bits/stdc++.h>
#include<iostream>
using namespace std;
//int a[10008];
int main()
{
    char a1[106],b1[106],c1[106];
    cin >> a1;
    cin >> b1 ;
    cin >> c1;
    queue<char>a,b,c;
    for(int i=0;i<strlen(a1);i++)
    {
        a.push(a1[i]);
    }
    for(int i=0;i<strlen(b1);i++)
    {
        b.push(b1[i]);
    }
    for(int i=0;i<strlen(c1);i++)
    {
        c.push(c1[i]);
    }
    char jk=a.front();
    a.pop();
    while(1)
    {
        if(jk=='a')
        {
            if(a.empty())
            {
               cout << "A";
               return 0;
            }
            else
            {
                jk=a.front();
                a.pop();
            }
        }
        else if(jk=='b')
        {
            if(b.empty())
            {
                cout << "B" ;
                return 0;
            }
            else
            {
                jk=b.front();
                b.pop();
            }
        }
        else
        {
            if(c.empty())
            {
                cout << "C" ;
                return 0;
            }
            else
            {
                jk=c.front();
                c.pop();
            }
        }
    }
    return 0;
}

L Daisy Chains

Every day, as part of her walk around the farm, Bessie the cow visits her favorite pasture, which has N flowers (all colorful daisies) labeled 1…N lined up in a row (1≤N≤100). Flower i has pi petals (1≤pi≤1000).
As a budding photographer, Bessie decides to take several photos of these flowers. In particular, for every pair of flowers (i,j) satisfying 1≤i≤j≤N, Bessie takes a photo of all flowers from flower i to flower j (including i and j).

Bessie later looks at these photos and notices that some of these photos have an “average flower” – a flower that has P petals, where P is the exact average number of petals among all flowers in the photo.

How many of Bessie’s photos have an average flower?
样例输入 Copy
4
1 1 2 3
样例输出 Copy
6
思路:由于数据小,暴力前缀和即可

#include<bits/stdc++.h>
#include<iostream>
using namespace std;
//int a[10008];
 int a[101],b[101];
int main()
{

    int n,sum=0,f;
    double avr;
    cin >> n;
    for(int i=1;i<=n;i++)
    {
        cin >> a[i];
        b[i]=b[i-1]+a[i];   //前缀和
    }
    for(int j=1;j<=n;j++)
    {
        for(int i=1;i<=j;i++)
        {
            int s=b[j]-b[i-1];
            f=0;
			avr=s*1.0/(j-i+1);    //注意这里数据应该是double型的
            for(int t=i;t<=j;t++)
            {
                if(a[t]==avr)
                {
                    f=1;
                }
            }
            if(f==1)
            {
                sum++;
            }
        }
    }
    cout << sum << endl;
    return 0;
}

D: 花生采摘

鲁宾逊先生有一只宠物猴,名叫多多。这天,他们两个正沿着乡间小路散步,突然发现路边的告示牌上贴着一张小小的纸条:“欢迎免费品尝我种的花生!——熊字”。
鲁宾逊先生和多多都很开心,因为花生正是他们的最爱。在告示牌背后,路边真的有一块花生田,花生植株整齐地排列成矩形网格(如图1)。有经验的多多一眼就能看出,每棵花生植株下的花生有多少。为了训练多多的算术,鲁宾逊先生说:“你先找出花生最多的植株,去采摘它的花生;然后再找出剩下的植株里花生最多的,去采摘它的花生;依此类推,不过你一定要在我限定的时间内回到路边。”
我们假定多多在每个单位时间内,可以做下列四件事情中的一件:

  1. 从路边跳到最靠近路边(即第一行)的某棵花生植株;
  2. 从一棵植株跳到前后左右与之相邻的另一棵植株;
  3. 采摘一棵植株下的花生;
  4. 从最靠近路边(即第一行)的某棵花生植株跳回路边。
    现在给定一块花生田的大小和花生的分布,请问在限定时间内,多多最多可以采到多少个花生?注意可能只有部分植株下面长有花生,假设这些植株下的花生个数各不相同。
    例如在图2所示的花生田里,只有位于(2, 5), (3, 7), (4, 2), (5, 4)的植株下长有花生,个数分别为13, 7, 15, 9。沿着图示的路线,多多在21个单位时间内,最多可以采到37个花生。
    输入
    输入的第一行包括三个整数,M, N和K,用空格隔开;表示花生田的大小为M * N(1 <= M, N <= 20),多多采花生的限定时间为K(0 <= K <= 1000)个单位时间。接下来的M行,每行包括N个非负整数,也用空格隔开;第i + 1行的第j个整数Pij(0 <= Pij <= 500)表示花生田里植株(i, j)下花生的数目,0表示该植株下没有花生。
    输出
    输出包括一行,这一行只包含一个整数,即在限定时间内,多多最多可以采到花生的个数。
    样例输入 Copy
    6 7 21
    0 0 0 0 0 0 0
    0 0 0 0 13 0 0
    0 0 0 0 0 0 7
    0 15 0 0 0 0 0
    0 0 0 9 0 0 0
    0 0 0 0 0 0 0
    样例输出 Copy
    37
    思路:虽然明知是个模拟,但开始还是被唬住了,突然想到开个优先队列就好了,嘻嘻,具体看代码吧
#include <bits/stdc++.h>
using namespace std;
int main()
{
	priority_queue<int, vector<int>, less<int> > jk;  //会帮你把数据排好序的
	int n,m,k,x1=-1,y1=-1;     //初始化位置
	int a[30][30];      
	int sum=0,num=0;
	cin >> m >> n >> k;
	for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            cin >> a[i][j];
            jk.push(a[i][j]);   //存进队列
        }
    }
    int f=0,i=0,j=0,f1=0; 
    while(!jk.empty())      //一个结束条件就是都跑了一遍,就是队列空了
    { 
        int t=jk.top();    //获取当前最大的
        jk.pop();         //出队
        for( i=0;i<m;i++)  
        {
            for( j=0;j<n;j++)
            {
                if(a[i][j]==t)
                {
					f1=1;   
					break;
				}
            }
            if(f1==1)   //开始忘了,一顿调才发现这东西没写
            {
              f1=0;
               break;   
            }
        }
        if(f==0)     //如果是第一次,花费时间就是行数加一
        {
            f=1;
            sum+=i+1;
            //cout << i << " " << j << endl;
        }

        else
        {
            sum+=abs(x1-i)+abs(y1-j)+1;   
        }
        x1=i;
        y1=j;
        //cout << num << " " << sum <<endl;
        if(sum+2+i<=k)   //看看采这个回去超不超时
        {
            num+=t;     
        }
        else
        {
            break;   //超时就结束了
        }
    }
    cout << num << endl;
	return 0;
}

总结

感觉对我是个stl专场。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

\ 安 /

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值