2019年暑假集训第十套题

问题 A: 手链的价值

题目描述

通过几年的努力,小C成功晋级国家集训队,成功被保送清华大学,为了庆祝,叶老师决定送小C一个礼物。
在珠宝店,叶老师终于发现一种既便宜又大气的手链。
手链的价格是看手链上的宝石决定的,每一种宝石的价值不同。
具体规则以下:
宝石A的价值是一、宝石B的价值是二、宝石C的价值是3·····宝石Z的价值是26。
为了防止被销售员虚报价格,叶老师决定请你帮忙计算一下手链的价值。node

输入

本题有T组数据。
对于每组数据只有一行。
1≤T≤20
1≤手链长度≤100000ios

输出

输出结果,并换行。c++

样例输入

2 
ABCD
LOVELOVE

样例输出

10
108

题解:

个人写法比较蠢,也就是安全

用26个if判断一下,而后sum求和spa

源代码:

#include<bits/stdc++.h>
using namespace std;
char a[100005];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>a;
        int sum=0;
        for(int i=0;i<strlen(a);i++)
        {
            if(a[i]=='A')sum+=1; 
            else if(a[i]=='B')sum+=2;
            else if(a[i]=='C')sum+=3;
            else if(a[i]=='D')sum+=4;
            else if(a[i]=='E')sum+=5;
            else if(a[i]=='F')sum+=6;
            else if(a[i]=='G')sum+=7;
            else if(a[i]=='H')sum+=8;
            else if(a[i]=='I')sum+=9;
            else if(a[i]=='J')sum+=10;
            else if(a[i]=='K')sum+=11;
            else if(a[i]=='L')sum+=12;
            else if(a[i]=='M')sum+=13;
            else if(a[i]=='N')sum+=14;
            else if(a[i]=='O')sum+=15;
            else if(a[i]=='P')sum+=16;
            else if(a[i]=='Q')sum+=17;
            else if(a[i]=='R')sum+=18;
            else if(a[i]=='S')sum+=19;
            else if(a[i]=='T')sum+=20;
            else if(a[i]=='U')sum+=21;
            else if(a[i]=='V')sum+=22;
            else if(a[i]=='W')sum+=23;
            else if(a[i]=='X')sum+=24;
            else if(a[i]=='Y')sum+=25;
            else if(a[i]=='Z')sum+=26;
        }
        cout<<sum<<endl;
    }
}

问题 B: 笔记本

题目描述

FST是一名可怜的小朋友,他很强,可是常常fst,因此rating一直低迷。
可是重点在于,他很是适合ACM!并在最近的区域赛中得到了不错的成绩。
拿到奖金后FST决定买一台新笔记本,可是FST发现,在价格能承受的范围内,笔记本的内存和速度是不可兼得的。
但是,有一些笔记本是被另一些“完虐”的,也就是内存和速度都不高于另外某一个笔记本,如今FST想统计一下有多少笔记本被“完虐”。code

输入

第一行一个正整数n,
表示笔记本的数量。
接下来n行,每行两个正整数Mi,Si表示这款笔记本的内存和速度。
n≤105,Mi,Si≤109排序

输出

一行,一个正整数,表示被完虐的笔记本数。内存

样例输入

4
100 700
200 500
50 100
300 400

样例输出ci

1

提示

Mi和Si都是越大越优。
数据保证Mi互不相同,Si也互不相同。it

题解:

先对一种特征(我用的是内存)进行排序(降序),令t[i]为s[1]~s[i]中速度最快的

那么若是s[i]的速度t[i-1]慢,说明这台笔记本被“完虐”了,ans++.

源代码:

#include<bits/stdc++.h> 
using namespace std;
struct node
{
    int m,s;
}s[400010];
int cmp(node a,node b)
{
   return a.m>b.m;//降序
}
int t[800010];
int main()
{
    int i,j,n,num,k,maxx,ans=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d",&s[i].m,&s[i].s);
    }
    sort(s+1,s+1+n,cmp);
    t[1]=s[1].s;
    for(i=2;i<=n;i++)t[i]=max(t[i-1],s[i].s);//求s[i]~s[i]中的最快速度
    for(i=2;i<=n;i++)
    {
        if(t[i-1]>s[i].s)ans++;//被“完虐”了
    }
    printf("%d\n",ans);
}
​

问题 C: 机器人

题目描述

从前在月球上有一个机器人。
月球能够看做一个 n*m 的网格图,每一个格子有三种可能:空地,障碍,机器人(有且仅有一个),如今地面指挥中心想让机器人在月球上行走,每次能够发送一个指令,为 U-往上走、D-往下走、L-往左走、R-往右走的其中之一。
当机器人接收到一个行走指令时,若是即将到达的位置为障碍物,那么机器人将留在原地,不然机器人向对应方向走一步,若是其走出边界那么当即死亡。
地面指挥中心固然不想让机器人就这么挂掉,所以其定义一个操做序列是安全的,当且仅当机器人按此操做序列走不会死亡。
可是从地球向月球发信息不是个容易的事,并且有时候某些指令还会在茫茫宇宙中被吞没,好比指挥中心传出去 RUR 指令,到机器人那里就可能变成 RR 或者变成 U,所以定义一个操做序列是绝对安全的当且仅当其任意子序列都是安全的。
如今地面指挥中心想知道,对于某一个地图,绝对安全的操做序列最长能够到多少,若是存在一个长度为正无穷的这样的序列,那么输出-1。 

输入

输入文件为“robot.in” 
第一行有两个正整数 n, m,表示网格图的大小, 接下来 n 行,每行 m 个字符,表示这张网格图。
其中字符“.”表示空地,“#”表示障碍物,“S”表示机器人所在位置。 

输出

输出文件为“robot.out” 
输出一个整数, 表示绝对安全的操做序列最长能够到多少 

样例输入

5 5

#####

#...# 

.#S#. 

#...# 

#####

样例输出

-1

提示

【数据范围】 

对于100%的数据,1 <= n, m <= 50 

题解:

一、若机器人的四面的其中一面有障碍物。

那么这个序列必定是正无穷大的,由于机器人碰到障碍物会停下来

二、若是四个方向都没有障碍物

若是这个地图是5*5的,且机器人的四个方向没有障碍物,

机器人处于地图中心,那么它走的长距离就是5-1+5-1=8

由于处于地图中心,说明它要不越界,最多能够向左两格

向右两格,向上两格,向下两格。综合一下,也就是横向

不超四格,上下不超四格   4+4=5-1+5-1=n-1+m-1

源代码:

#include<bits/stdc++.h>
using namespace std;
char a[51][51];
int n,m;
int tx,ty;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
       {
            cin>>a[i][j];
            if(a[i][j]=='S')
            {
                tx=i;
                ty=j;
            }
       }
    bool flag=false;
    for(int i=1;i<=n;i++)
       if(a[i][ty]=='#')flag=true;
    for(int i=1;i<=m;i++)
       if(a[tx][i]=='#')flag=true;
    if(flag==true)cout<<-1<<endl;
    else
        cout<<n-1+m-1<<endl;
}

问题 D: 办公室钥匙

题目描述

有n我的和k把钥匙在一条直线上,每一个人都想去位于直线p点的办公室找陈老师问题目。陈老师不但愿被打扰,因此他把办公室门锁了,为了进入办公室,每一个人须要到达直线某一点来拿到办公室钥匙,拿着办公室钥匙才能进入办公室,一我的进门后会把门再锁上,因此每一个人都须要带着钥匙才能进门。 

你如今须要安排每一个人如何行动使得n我的都进入办公室所须要的时间最短。假设每一个人移动一个单位要花一秒钟。 

注意:1. 不计拿钥匙、开门进门等时间,只计算人移动的时间;2. 一旦某个位置的钥匙被某我的拿走了,它不能再被其余人拿走;3. 若是两我的同时到某个存在钥匙的点,只有一我的能够拿钥匙;4. 一我的能够通过一个有钥匙的点而不拿钥匙;5. 钥匙只能由人带着不能放下;6. 全部人能够同时行动。 

输入

输入文件为“key.in” 

第一行为三个用空格分隔的整数 n, k, p,分别表示人的数量,钥匙的数量和办公室的位置;   

第二行为 n个用空格隔开的整数,表示每一个人的位置xi ,保证每一个人的位置都不一样,可是不保证顺序。 

第三行为k个用空格隔开的整数,表示每把钥匙的位置bi ,保证每把钥匙的位置都不一样,可是不保证顺序。 

(注意输入数据中同一个点不会有超过一我的或者超过两把钥匙,可是同一个点可能会同时有一我的和一把钥匙) 

输出

输出文件为“key.out” 

输出仅一个整数,表示n我的都进入办公室的所花的最短期。 

样例输入

样例输出

提示

【样例解释】 

在第一个例子中,位于点20的人应该拿着位于点40的钥匙而且将它带到位于点50的办公室。他花费30秒。位于点100的人能够拿着位于点80的钥匙并随身携带到办公室。他花了50秒。所以,50秒后,每一个人都带着钥匙在办公室。。   

【数据范围】 

对于50%的数据,1≤n≤10, n≤k≤20, 1≤p, xi, bi≤1000 

对于100%的数据,1≤n≤100000, n≤k≤200000, 1≤p, xi, bi≤109 

不是AC的题解!!(RE还来秀)

这题的数据量真的大...QAQ*3

这题乍一看,就是一道暴力题,因而本蒟蒻

就这样写了。结果RE了,只得了50分。

下面讲一下本蒟蒻的暴力思路:

枚举第i人的最短期,用ans[i]储存起来最后取大值(由于能够同时行动,因此时间最长的就是最终用时)

50分代码:

#include<bits/stdc++.h>
#include<iostream>
#define ll long long
using namespace std;
int n,k,p;
ll x[10005];
ll b[20005];
ll ans[10005]; 
ll cnt=-1,sum=0,tmp=0;
int min(int a,int b)
{
    if(a<=b)return a;
    else return b;
}
int max(int a,int b)
{
    if(a>=b)return a;
    else return b;
}
int main()
{
    cin>>n>>k>>p;
    memset(ans,0x7f,sizeof(ans));
    for(int i=1;i<=n;i++)cin>>x[i];
    for(int i=1;i<=k;i++)cin>>b[i];
    //sort(x+1,x+1+n);
    //sort(b+1,b+1+k);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=k;j++)
        {
            tmp=abs(b[j]-x[i]);
            sum=abs(p-b[j])+tmp;
            ans[i]=min(sum,ans[i]);
        }
    }
    for(int i=1;i<=n;i++)
    {
        cnt=max(cnt,ans[i]);
    }
    cout<<cnt<<endl;
}