2017年西南民族大学程序设计竞赛-网络同步赛

A.星图
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述

现在有一个N*M的矩形星图。其中包括恒星和黑洞。恒星可以向上、下、左、右发射光束,且允许光束从其中穿过;黑洞会吸收所有经过的光束。
若一颗恒星向上、下、左、右发射光束,你能告诉我,该光束能否避免被黑洞吸收,进入星图之外的区域么?

输入描述:
单组输入。第一行三个正整数N,M,Q(1 <= N,M
<= 1000,1 <= Q <= 1000000),分别表示矩阵的行列,以及询问的个数,询问之间相互独立。
然后一个N*M的矩阵,由’’和’#’构成,表示星图。’’表示恒星,’#’表示黑洞。
最后Q行,表示Q个询问,每行两个正整数x,y(1 <= x <= N, 1 <= y
<= M)表示发光恒星的位置(从上往下数第x行,从左往右数第y列,且保证该位置一定是恒星)和一个字符p(p∈{‘L’, ‘R’,
‘D’, ‘U’},’R’表示向右;’L’表示向左;’D’表示向下’;’U’表示向上)表示该恒星产生光束的方向。
输出描述:
一共Q行。对于每个询问,若该恒星发出的光束能够进入星图之外的区域则输出“YES”;否则输出“NO”。(不包含引号)
示例1
输入

4 5 5
**##*
*****
*#*#*
##**#
2 3 D
2 3 U
1 5 R
4 4 U
3 1 U
输出
YES
NO
YES
NO
YES

分析:一看到这题 条件反射了,直接dfs TLE。。 从边上开始,再TLE
后来看到别人写的。。 我可能是暴力用太多了 欠思考。。

用数组记录第一个的横坐标或者纵坐标,具体见代码

#include <bits/stdc++.h>
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
#define rep(i,a,n) for(int i=a;i<n;i++)
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef unsigned long long ull;
const double eps=1e-6;
const int INF=0x3f3f3f3f;
const int N=1e3+5;
char s[N][N],a[N][N];
int l[N],r[N],d[N],u[N];
///l数组记录一行中从左至右的第一个#的纵坐标,r数组记录从右往左的第一个纵坐标
///d数组记录一列中从下至上的第一个#的横坐标,u数组记录从上往下的第一个横坐标
int main()
{
    int n,m,q;
    while(~scanf("%d%d%d",&n,&m,&q))
    {
        mem(u,INF);
        mem(l,INF);
        rep(i,1,n+1)
        {
            bool flag=1;
            scanf("%s",s[i]+1);
            rep(j,1,m+1)
            if(s[i][j]=='#')
            {
                if(flag) flag=0,l[i]=j;
                r[i]=j;
                d[j]=i;
            }
        }
        rep(j,1,m+1)
        rep(i,1,n+1)
        if(s[i][j]=='#')
        {
            u[j]=i;
            break;
        }
        int x,y;
        char ch;
        rep(i,0,q)
        {
            scanf("%d %d %c",&x,&y,&ch);
            if(ch=='D') printf("%s\n",d[y]<x?"YES":"NO");
            if(ch=='U') printf("%s\n",u[y]>x?"YES":"NO");
            if(ch=='R') printf("%s\n",r[x]<y?"YES":"NO");
            if(ch=='L') printf("%s\n",l[x]>y?"YES":"NO");
        }
    }
    return 0;
}

装进肚子
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
自从ZZZZone吃完糖果后,他开始改吃巧克力了,他每天想吃n个巧克力增在甜蜜值,他决定早上吃K个巧克力,晚上吃n - K个巧克力,每个巧克力在早上吃和在晚上吃的甜蜜值是不一样的,他想让自己得到的甜蜜值最大,并想知道最大是多少。
请你编程帮助他。
输入描述:
第一行包含两个数n,K表示每天要吃的巧克力数量和要在早上吃的数量。(n <= 100000, K <= n)
第二行包含n个整数Ai(1 <= i <= n) 表示个第i个巧克力在早上吃可得到的甜蜜值 (Ai <= 100000)
第三行包含n个整数Bi(1 <= i <= n) 表示个第i个巧克力在晚上吃可得到的甜蜜值 (Bi <= 100000)
输出描述:
输出仅一行包含一个整数表示ZZZZone能获得的最大甜蜜值。
示例1
输入
2 1
3 6
2 8
输出
11
说明
早上吃第一个巧克力得到3甜蜜值,晚上吃第2个巧克力得到8的甜蜜值,所以最大可得到11的甜蜜值。

分析:必须有k个在早上吃。 求最大甜蜜值 (贪心)
也就是早晚的差值最大,排序
结果可能超出int ,用long long

#include <bits/stdc++.h>
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
#define rep(i,a,n) for(int i=a;i<n;i++)
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef unsigned long long ull;
const double eps=1e-6;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int N=1e5+5;
struct Node
{
    int a,b;
    bool operator < (const Node& m)const
    {
        return a-b>m.a-m.b;
    }
}a[N];
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        rep(i,0,n) scanf("%d",&a[i].a);
        rep(i,0,n) scanf("%d",&a[i].b);
        sort(a,a+n);
        ll ans=0;
        rep(i,0,k) ans+=a[i].a;
        rep(i,k,n) ans+=a[i].b;
        printf("%lld\n",ans);
    }
    return 0;
}

E 求出相邻块颜色不同的 tmp=m*(m-1)^(n-1)
ans=m^n-tmp;

小猪佩奇练打字
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
猪妈妈让佩奇练习打字, 她给了佩奇一篇只有小写字母的字符串S ( 1 <= |S| <= 105)。 但是佩奇记不住键盘字母的位置,只能看着键盘一个一个打。淘气的乔治趁佩奇不注意, 偷偷的换了键盘按键的位置。 乔治是这样操作的:乔治每次扣下来两个键帽, 并且将这两个键帽互换位置重新安回去, 乔治越玩越起劲,一直重复了m(1 <= m <= 105)次。请输出佩奇打完字后屏幕上显示的实际字符串。
输入描述:
第一行输入一个字符串S ( 1 <= |S| <= 105);
第二行输入一个数字m(1 <= m <= 105), 表示佩奇要操作m次。
之后有m行, 每行有两个字母 c1, c2 表示佩奇要把这两个键帽互换位置。
输出描述:
输出一行字符串, 即佩奇用乔治玩坏的键盘输出的实际字符串。
示例1
输入
helloworld
3
e o
h z
l p
输出
zoppewerpd
备注:
|S| 是字符串s长度

char s[N],ch[30];
int main()
{
    int n;
    while(~scanf("%s",s))
    {
        rep(i,0,26) ch[i+'a']=i+'a';
        scanf("%d",&n);
        char ch1,ch2;
        rep(i,0,n)
        {
            scanf(" %c %c",&ch1,&ch2);
            char tmp=ch[ch1];
            ch[ch1]=ch[ch2];
            ch[ch2]=tmp;
        }
        rep(i,0,strlen(s)) putchar(ch[s[i]]);
        puts("");
    }
    return 0;
}

免费WiFi
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
TRDD开了一家免费WiFi体验店, 所有人都可以免费连接WiFi, 只有一个条件, 你要提前一天预约。今天,TRDD收到了n(1 <= n <=1000)个人的预约, 每个人有一个时间段[L, R] (1 <= L <= R <= 5000)表示这个人预约连接WiFi从L时刻到R时刻。 但是市面上只有一种路由器, 这种路由器单台最多能同时连接m(n <= 100)台设备, TRDD想要知道最少使用多少台路由器就能保证明天每个人都能连上WiFi。
输入描述:
第一行包含两个数n(1 <= n <=1000), m (1 <= m <= 100)表示今天有n个人预约, 以及路由单台最大连接个数m。
之后有n行, 第i行有两个数字 [L, R] (1 <= L <= R <= 5000) 表示第i个人预约连接WiFi的时间是从L到R。
输出描述:
输出一个数字表示TRDD最少需要开启的路由器的个数。
示例1
输入
4 1
1 5
2 7
3 4
6 9
输出
3

分析:因为求的是最少个数, 将时间段内的最大值sum找出,ans=int(ceil(1.0*sum/m))

int cnt[N];
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        mem(cnt,0);
        while(n--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            rep(i,l,r+1) cnt[i]++;
        }
        sort(cnt,cnt+N);
        printf("%d\n",int(ceil(1.0*cnt[N-1]/m)));
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值