2020年牛客算法入门课练习赛3 A.dfs B.容斥原理 C.线段树 D.弗洛伊德+DP E.数学题

链接:https://ac.nowcoder.com/acm/problem/208246
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
每逢佳节胖三斤,牛牛在过去的节日里长胖了,连拐弯都困难,甚至会卡在门上,所以他很讨厌拐弯。给你一个N*N(2≤N≤100)的方格中,‘x’表示障碍,‘.’表示没有障碍(可以走),牛牛可以从一个格子走到他相邻的四个格子,但是不能走出这些格子。问牛牛从A点到B点最少需要转90度的弯几次。

输入描述:
第一行一个整数:N,下面N 行,每行N 个字符,只出现字符:‘.’,‘x’,‘A’,‘B’;表示上面所说的矩阵格子,每个字符后有一个空格。

输出描述:
一个整数:最少转弯次数。如果不能到达,输出-1。
示例1
输入
复制
3
. x A
. . .
B x .
输出
复制
2
备注:
开始和结束时的方向任意。

#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <cstring>
#include <vector>
#include<cstdio>
using namespace std;
char mp[110][110];
int vis[110][110];
int res=0x3f3f3f3f;
int sx,sy,zx,zy;
int dx[]={1,-1,0,0};
int dy[]={0,0,-1,1};
 int n;
void dfs(int x,int y,int sum,int st){
	if(mp[x][y]=='B'){
		res=min(res,sum);
		return ;
	}
	if(sum>=res)return ;
	for(int i=0;i<4;i++){
		int xx=x+dx[i];
		int yy=y+dy[i];
		if(xx>=0&&xx<n&&yy>=0&&yy<n&&!vis[xx][yy]&&mp[xx][yy]!='x'){
			if(st==-1){
				vis[xx][yy]=1;
				dfs(xx,yy,sum,i);
				vis[xx][yy]=0;
			}
			else if(st!=i){
					vis[xx][yy]=1;
				dfs(xx,yy,sum+1,i);
				vis[xx][yy]=0;
			}
			else {
						vis[xx][yy]=1;
				dfs(xx,yy,sum,i);
				vis[xx][yy]=0;
			}
		}
	}

}
int main()
{
  
   cin>>n;
  for(int i=0;i<n;i++){
  	for(int j=0;j<n;j++){
  		cin>>mp[i][j];
	  }
  }
   for(int i=0;i<n;i++)
   	for(int j=0;j<n;j++)
   		if(mp[i][j]=='A'){
		   vis[i][j]=1;
   	    dfs(i,j,0,-1);
   	}
   if(res==0x3f3f3f3f)cout<<-1<<endl;
   else
   cout<<res<<endl;
  return 0;
}

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

题目描述
牛牛是怎么胖的呢?当然是因为他太热爱吃零食了,牛牛给他的每一份零食编了号,每次他会拿出编号在[a,b]区间里能被8整除却不能被另外一些数中的任意一个整除的零食吃掉。现在请你帮他算一算他这一次到底能吃多少份零食吧?

输入描述:
第一行一个数n,代表不能被整除的数的个数。
第二行n个数,中间用空格隔开。
第三行两个数a,b,中间一个空格。
输出描述:
一个整数,为牛牛能吃到的零食份数,也就是[a,b]间中能被8整除却不能被给出的那n个数中任意一个整除的数的个数。
示例1
输入
复制
3
7764 6082 462
2166 53442
输出
复制
6378
说明
1≤n≤15,1≤a≤b≤10^9

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
ll ans, s[25], a, b;
int n;
ll lcm(ll x, ll y)
{
    return x * y / __gcd(x, y);
}
void dfs(ll x, ll y, ll t)
{
    if (y > b)
        return;
    if (x & 1)
        ans += b / t - a / t;
    else
        ans -= b / t - a / t;
    for (int i = y + 1; i <= n; i++)
    {
        dfs(x + 1, i, lcm(t, s[i]));
    }
    return;
}
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld", &s[i]);
    }
    scanf("%lld%lld", &a, &b);
    a--;
    dfs(1, 0, 8);
    printf("%lld", ans);
    return 0;
}

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

题目描述
牛牛为了减(吃)肥(好),希望对他的零食序列有更深刻的了解,所以他把他的零食排成一列,然后对每一个零食的美味程度都打了分,现在他有可能执行两种操作:
eat k:吃掉当前的第k个零食。右边的零食全部往左移动一位(编号减一)。
query i j:查询当前第i个零食到第j个零食里面美味度最高的和最低的零食的美味度。

输入描述:
第一行包含两个数n, m,表示原始数组的元素个数和操作的个数。第二行包括n个数,表示原始数组。以下m行,每行格式为1 k或者2 i j,其中第一个数为1表示吃掉,为2表示询问。

输出描述:
对每个询问操作输出一行,包括两个数,表示该范围内的最小值和最大值。
示例1
输入
复制
10 4
1 5 2 6 7 4 9 3 1 5
2 2 8
1 3
1 6
2 2 8
输出
复制
2 9
1 7
说明
1<=n, m<=1e6, 1<=m<=1e6,数组中的元素绝对值均不超过1e9
备注:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
ll x;
ll maxx[maxn << 2], minn[maxn << 2], tr[maxn << 2];
const int inf = 0x3f3f3f3f;
#define lson p << 1, l, mid
#define rson p << 1 | 1, mid + 1, r
void pushup(ll p)
{
    maxx[p] = max(maxx[p << 1], maxx[p << 1 | 1]);
    minn[p] = min(minn[p << 1], minn[p << 1 | 1]);
    tr[p] = tr[p << 1] + tr[p << 1 | 1];
}
void build(ll p, ll l, ll r)
{
    if (l == r)
    {
        scanf("%lld", &x);
        maxx[p] = minn[p] = x;
        tr[p] = 1;
        return;
    }
    ll mid = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(p);
}
void del(ll o, ll p, ll l, ll r)
{
    if (l == r)
    {
        tr[p] = 0;
        minn[p] = inf;
        maxx[p] = -inf;
        return;
    }
    ll mid = (l + r) >> 1;
    if (o <= mid)
        del(o, lson);
    else
        del(o, rson);
    pushup(p);
}
ll qmin(ll ql, ll qr, ll p, ll l, ll r)
{
    if (ql <= l && r <= qr)
    {
        return minn[p];
    }
    ll mid = (l + r) >> 1;
    ll ans = inf;
    if (ql <= mid)
    {
        ans = min(ans, qmin(ql, qr, lson));
    }
    if (qr > mid)
    {
        ans = min(ans, qmin(ql, qr, rson));
    }
    return ans;
}
ll qmax(ll ql, ll qr, ll p, ll l, ll r)
{
    if (ql <= l && r <= qr)
    {
        return maxx[p];
    }
    ll mid = (l + r) >> 1;
    ll ans = -inf;
    if (ql <= mid)
    {
        ans = max(ans, qmax(ql, qr, lson));
    }
    if (qr > mid)
    {
        ans = max(ans, qmax(ql, qr, rson));
    }
    return ans;
}
ll qid(ll p, ll l, ll r, ll o)
{
    if (l == r)
    {
        return l;
    }
    ll mid = (l + r) >> 1;
    if (tr[p << 1] >= o)
        return qid(lson, o);
    else
        return qid(rson, o - tr[p << 1]);
}
int main()
{
    ll n, m;
    scanf("%lld%lld", &n, &m);
    build(1, 1, n);
    int op, x, y;
    ll pos, posr;
    while (m--)
    {
        scanf("%d", &op);
        if (op == 1)
        {
            scanf("%d", &x);
            pos = qid(1, 1, n, x);
            del(pos, 1, 1, n);
        }
        else
        {
            scanf("%d%d", &x, &y);
            pos = qid(1, 1, n, x);
            posr = qid(1, 1, n, y);
            printf("%lld %lld\n", qmin(pos, posr, 1, 1, n), qmax(pos, posr, 1, 1, n));
        }
    }

    return 0;
}

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
题目描述
牛牛为了奖励自己减肥成功( 并没有),奖励自己去X市旅游,X市有N个地点,这些点之间有M条长度不同的边,他们组成了一张有向无环图,牛牛希望从一个点X到另外一个点Y走密度最小的一条路,所谓密度是指的从X到Y的总路程长度除以X到Y走过的边的数量。现在牛牛提出Q个询问,每次询问一对Xi,Yi,请你输出Xi到Yi密度最小的路径密度。

输入描述:
第一行包括2个整数N和M。

以下M行,每行三个数字u、v、w,表示从u点到v点有一条权值为w的有向边。
再下一行有一个整数Q。
以下Q行,每行一个询问X和Y,求X到Y的最小密度路径
输出描述:
对于每个询问输出一行,表示该询问的最小密度路径的密度(误差在1e-3范围内即可),如果不存在这么一条路径输出“OMG!”(不含引号)。
示例1
输入
复制
3 3
1 3 5
2 1 6
2 3 6
2
1 3
2 3
输出
复制
5.000
5.500
说明
1 ≤ N ≤ 50,1 ≤ M ≤ 1000,1 ≤ W ≤ 100000,1 ≤ Q ≤ 100000。

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
#include <climits>
#include <stack>
#include <map>
#include <cmath>
#include <set>
using namespace std;
typedef long long ll;
const int mod = 1e4 + 7;
const int inf = 0x3f3f3f3f;
int dp[60][60][60];
double ans[60][60];
template <class T>
void read(T &x)
{
    ll f = 1;
    x = 0;
    char c = getchar();
    while (!isdigit(c))
    {
        f = -1;
        c = getchar();
    }
    while (isdigit(c))
    {
        x = x * 10 + c - 48;
        c = getchar();
    }
    x *= f;
}
template <class T>
void write(T x)
{
    if (x < 0)
    {
        putchar('-');
        x = -x;
    }
    if (x > 9)
    {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}
int main()
{
    int n, m;
    read(n);
    read(m);
    int u, v, w;
    memset(dp, 0x3f, sizeof(dp));
    for (int i = 1; i <= n; i++)
    {
        dp[i][i][0] = 0;
    }
    for (int i = 0; i < m; i++)
    {
        read(u);
        read(v);
        read(w);
        dp[u][v][1] = min(w, dp[u][v][1]);
    }
    for (int p = 2; p <= n; p++)
    {
        for (int k = 1; k <= n; k++)
        {
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= n; j++)
                {
                    dp[i][j][p] = min(dp[i][j][p], dp[i][k][p - 1] + dp[k][j][1]);
                }
            }
        }
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            ans[i][j] = inf;
            if (i == j)
                continue;
            for (int p = 1; p <= n; p++)
            {
                if (dp[i][j][p] < inf)
                {
                    ans[i][j] = min(ans[i][j], dp[i][j][p] * 1.0 / p);
                }
            }
        }
    }
    int q;
    read(q);
    while (q--)
    {
        read(u);
        read(v);
        if (ans[u][v] < inf)
            printf("%.3f\n", ans[u][v]);
        else
            printf("OMG\n");
    }
    return 0;
}

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

题目描述
旅行完了的牛牛又胖了,于是他终于下决心要戒掉零食,所以他带着他最爱的土豆回到了牛星,开始了在牛星种土豆和只吃土豆减肥的日子。(吃土豆能减肥么?)经过了辛勤的劳作,牛牛种的土豆奇迹般的收获了,于是他得到了很多很多很多很多的土豆(实在太多,数不过来了,你可以认为是无穷个)。他将这很多很多个土豆按照重量从小到大进行了排序,每个土豆的编号依次为1、2、3……N,然后他就惊奇地发现:由于牛星球的土壤很奇特,第i个土豆的重量正好是3^(i-1) 。

现在牛牛饿了要吃掉其中的若干个土豆。他每次拿的土豆的数目是任意的,选的土豆也是任意的。选中的土豆的总重量即每个土豆重量之和。例如:牛牛这一次拿了第一个土豆和第三个土豆,那么总重量为1+9=10。

牛牛想知道,在所有的选土豆方案里,他可以获得的第k大的“总重量”是多少。

输入描述:
有多组输入样例。

第一行是一个整数T,表示有T组测试样例,0 ≤ T ≤ 70。

之后的T行中,每一行有一个数字k。(k<=2^31-1)

输出描述:
针对每一个测试样例,输出一行;格式为:
“Case #$Num: A ” , 其 中 , A”,其中, AN表示第Num组样例,$A表示他可以获得的第k大的总重量。
示例1
输入
复制
2
7
4
输出
复制
Case #1: 13
Case #2: 9
说明
土豆的重量依次为:1,3,9,27,81……

牛牛能够拿到的重量从小到大为:

1、3、4(=1+3)、9、10(=1+9)、12(=9+3)、13(=1+9+3)……

所以第7大的美观程度是13,第四大是9

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll solve(ll x){
    ll ans=0,t=1;
    while(x){
        if(x&1)ans+=t;
        t*=3;
        x>>=1;
    }
    return ans;
}
int main(){
   ll t,a;
   cin>>t;
  for(int i=1;i<=t;i++){
      cin>>a;
      printf("Case #%d: %lld\n",i,solve(a));
  }
  return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值