牛客寒假算法基础集训营4

A

Applese 的取石子游戏

Applese 和 Bpplese 在玩取石子游戏,规则如下:
一共有偶数堆石子排成一排,每堆石子的个数为 aiai。两个人轮流取石子,Applese先手。每次取石子只能取最左一堆或最右一堆,且必须取完。最后取得的石子多者获胜。假设双方都足够聪明,最后谁能够获胜呢?

输入描述:

第一行是一个正偶数 n,表示石子的堆数。
第二行是 n 个正整数 a1,a2,…,ana1,a2,…,an,表示每堆石子的个数。

输出描述:

输出一个字符串“Applese”或“Bpplese”,表示胜者的名字。

 博弈,由于每次取石子只能取最左一堆或最右一堆,且必须取完,那么选择奇数和和偶数和中比较大的一项,但是堆数为偶数,这无论如何先手赢。所以直接输出就好了。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
int main() {
    int n,d;
    ios::sync_with_stdio(false),cin.tie(0);
    cin >> n;
    for (int i = 1;i <= n;i++) cin >> d;
    cout << "Applese" << endl;
    return 0;
}
BApplese 走方格

pplese 又写了一个游戏。

在这个游戏中,它位于一个 n 行 m 列的方阵中的左上角(坐标为(0, 0),行的序号为0∼n−10∼n−1,列的序号为0∼m−10∼m−1)。

现在它想不重复地走过所有格子(除了起点),最后回到左上角的一个方案。

每次只能往上下左右其中一个方向走一格。

输入描述:

仅一行两个整数 n 和 m,表示方阵的大小。保证大于1×11×1。

输出描述:

如果存在方案,则输出一行操作,包含"L"、"R"、"U"、"D",分别表示左、右、上、下。如果有多种方案,输出任意一种即可。
如果没有方案,则在一行中输出"-1"。

根据题意那么就是走到一条路的尾巴然后向下往回到第二格再往下往后走到底。。。最后回来直接往回走到起点

类似这种的,特判下2*n或者n*2的情况。

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    if(n==1&&m==2)printf("RL");
    else if(n==2&&m==1)printf("DU");
    else if(n==1||m==1)printf("-1");
    else if(n%2&&m%2)printf("-1");
    else if(n%2==1&&m%2==0)
    {
        int p=m;
        while(m)
        {
            m=m-2;
            if(p-2==m)printf("D");
            for(int i=2;i<n;i++)printf("D");printf("R");
            for(int i=2;i<n;i++)printf("U");if(m)printf("R");
        }
        printf("U");
        for(int i=1;i<p;i++)printf("L");
    }
    else
    {
        int j=n;
        while(n)
        {
            if(o==n)printf("R");
            n=n-2;
            for(int i=2;i<m;i++)printf("R");printf("D");
            for(int i=2;i<m;i++)printf("L");if(n)printf("D");
        }
        printf("L");
        for(int i=1;i<j;i++)printf("U");
    }
    return 0;
}
CApplese 走迷宫

精通程序设计的 Applese 双写了一个游戏。
在这个游戏中,它被困在了一个 n×mn×m 的迷宫中,它想要逃出这个迷宫。
在迷宫中,有一些方格是水池,只有当 Applese 处于水属性的时候才可以通过;有一些方格是岩浆,只有当 Applese 是火属性的时候可以通过;有一些方格是墙壁,无论如何都无法通过;另一些格子是空地(包括起点和终点),可以自由通过。

在一些空地上有神秘道具可以让 Applese 转换自己的属性(从水属性变为火属性或从火属性变为水属性,需要一个单位的时间)。

已知 Applese 在一个单位的时间内可以朝四个方向行走一格,且开始处于水属性,位于空地的道具拾取后只能在该处立即使用(或者不使用),且可以多次使用。求它走出迷宫需要的最少时间。

输入描述:

第一行两个正整数 n, m 表示迷宫的大小。
接下来 n 行,每行长度为 m 的字符串。描述地图。
其中 'S' 表示起点,'T' 表示终点,'.' 表示空地,'w'表示岩浆,'~'表示水池,'@' 表示道具,'#'表示障碍。
保证地图中的起点和终点只有一个,道具都位于空地。

输出描述:

输出一个整数,表示 Applese 走出迷宫的最短时间。特别地,如果 Applese 走不出迷宫,输出 "-1"。

bfs最短路,多一维用来存冰火属性

#include <bits/stdc++.h>
using namespace std;
const int maxn=107;
int n,m,sx,sy,vis[2][maxn][maxn];
char mp[maxn][maxn];
int dir[4][2]= {1,0,0,1,-1,0,0,-1};
struct node
{
    int x,y,sta,dis;
};
void bfs()
{
    queue<node> q;
    vis[0][sx][sy]=1;
    q.push(node{sx,sy,0,0});
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        int sta=now.sta,x=now.x,y=now.y,dis=now.dis;
        if(mp[x][y]=='T')
        {
            printf("%d\n",dis);
            return;
        }
        dis++;
        for(int i=0; i<4; i++)
        {
            int xx=x+dir[i][0],yy=y+dir[i][1];
            if(vis[sta][xx][yy])
                continue;
            vis[sta][xx][yy]=1;
            if(xx<1||xx>n||yy<1||yy>m||mp[xx][yy]=='#')
                continue;
            if((sta==0&&mp[xx][yy]=='w')||(sta==1&&mp[xx][yy]=='~'))
                continue;
            if(mp[xx][yy]=='T')
            {
                printf("%d\n",dis);
                return;
            }
            q.push(node{xx,yy,sta,dis});
        }
        if(mp[x][y]=='@')
        {
            if(vis[sta^1][x][y])
                continue;
            vis[sta^1][x][y]=1;
            q.push(node{x,y,sta^1,dis});
        }
    }
    printf("-1\n");
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
        scanf("%s",mp[i]+1);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
        {
            if(mp[i][j]=='S')
                sx=i,sy=j;
        }
    bfs();
    return 0;
}

D题dp不会跳过

EApplese 涂颜色

精通程序设计的 Applese 叕写了一个游戏。


在这个游戏中,有一个 n 行 m 列的方阵。现在它要为这个方阵涂上黑白两种颜色。规定左右相邻两格的颜色不能相同。请你帮它统计一下有多少种涂色的方法。由于答案很大,你需要将答案对 109+7109+7 取模。

输入描述:

仅一行两个正整数 n, m,表示方阵的大小。

输出描述:

输出一个正整数,表示方案数对 109+7109+7 取模。

 每一列,有 2n 种涂色方法,由于数据比较大,看了眼准备快速幂,想想py能用然后偷个懒了。。

n , m = map(int,input().split())
ans = 1
MOD = 1000000007
n = n % (MOD - 1)
t = 2
while( n != 0 ):
    if((n & 1) == 1):
        ans = ans * t % MOD
    n >>= 1
    t = t * t % MOD
print(ans)

 

GApplese 的毒气炸弹

链接:https://ac.nowcoder.com/acm/contest/330/G
来源:牛客网
 

众所周知,Applese 是个很强的选手,它的化学一定很好。


今天他又AK了一套题觉得很无聊,于是想做个毒气炸弹玩。

毒气炸弹需要 k 种不同类型元素构成,Applese一共有 n 瓶含有这些元素的试剂。

已知元素混合遵循 m 条规律,每一条规律都可以用 "x y c" 描述。

表示将第 x 瓶试剂混入第 y 瓶试剂或者把第 y 瓶试剂混入第 x 瓶试剂,需要消耗 c 的脑力。
 

特别地,除了这 m 条规律外,Applese 可以将任意两瓶相同元素的试剂混合,且不需要消耗脑力。

 

Applese 想要配出毒气炸弹,就需要使 S 中含有 1∼k1∼k 这 k 种元素。它想知道自己最少花费多少脑力可以把毒气炸弹做出来。

输入描述:

第一行为三个整数 n, m, k 表示 Applese 拥有的试剂的数量,混合规律的数量和所需的元素种类数。
第二行为 n 个整数 a1,a2,…,ana1,a2,…,an,分别表示每一瓶试剂的元素类型。
接下来m行,每行三个整数 x, y, c,含义如题目描述中所述。不保证 x, y的试剂种类不同。

输出描述:

输出一个正整数表示最小的耗费脑力。特别地,如果无法合成出毒气炸弹,输出 "-1"。

图论。。求最小生成树

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100005;
int n, m, k,c;
vector<int> G[maxn];
int t[maxn], f[maxn];
struct edge
{
    int u, v, w;
    bool operator < (const edge &rhs) const
    {
        return w < rhs.w;
    }
} e[maxn];
int find(int x)
{
    return x == f[x] ? x : f[x] = find(f[x]);
}
int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= n; ++i) scanf("%d", &t[i]);
    for(int i = 1; i <= k; ++i) f[i] = i;
    int u, v, w;
    while(m--)
    {
        scanf("%d%d%d", &u, &v, &w);
        if(t[u] != t[v])
        {
            e[c++] = (edge)
            {
                t[u], t[v], w
            };
        }
    }
    sort(e, e+c);
    ll sum = 0;
    int cnt = 1;
    for(int i = 0; i < c; ++i)
    {
        int u = find(e[i].u), v = find(e[i].v);
        if(u != v)
        {
            f[u] = v;
            cnt++;
            sum += e[i].w;
        }
    }
    if(cnt >= k) printf("%lld\n", sum);
    else puts("-1");
    return 0;
}

 

IApplese 的回文串

自从 Applese 学会了字符串之后,精通各种字符串算法,比如……判断一个字符串是不是回文串。


这样的题目未免让它觉得太无聊,于是它想到了一个新的问题。

如何判断一个字符串在任意位置(包括最前面和最后面)插入一个字符后能不能构成一个回文串?

输入描述:

仅一行,为一个由字母和数字组成的字符串 s。

输出描述:

如果在插入一个字符之后可以构成回文串,则输出"Yes", 否则输出"No"。

emmmmmm,如题意。。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
string s;
int f(int l,int r,int t)
{
    if(l>=r) return 1;
    if(s[l]==s[r]) return f(l+1,r-1,t);
    else if(!t) return 0;
    else return f(l,r-1,0)+f(l+1,r,0);
}

int main()
{
    cin>>s;
    if(f(0,s.length()-1,1)) cout<<"Yes";
    else cout<<"No";
}
JApplese 的减肥计划

Applese 最近又长胖了,于是它打算减肥——练习举重。


他在举重的时候用两只手往不同方向用力,从而把杠铃举起来。

已知 Applese 两只手分别产生的力的大小,以及它们之间的夹角,试求两力合力的大小。

输入描述:

仅一行三个整数 f1,f2,af1,f2,a,分别表示两只手产生的力的大小以及它们之间的夹角。

输出描述:

输出一个实数表示两力合力的大小,要求相对误差或绝对误差不超过 10−610−6。

严格来讲,如果你的答案是 a,而标准答案是 b,那么当 |a−b|max{1,|b|}≤10−6|a−b|max{1,|b|}≤10−6 时,你的答案会被认为是正确的。

物理题。。。

#include <bits/stdc++.h>
using namespace std;
#define PI 3.14159265
int main()
{
    int f1,f2,a;
    double q;
    scanf("%d%d%d",&f1,&f2,&a);
    q=f1*f1+f2*f2+2*f1*f2*cos(1.0*a/180*PI);
    q=sqrt(q);
    printf("%.10f",q);
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值