计蒜客初赛3练习赛

25 篇文章 0 订阅
14 篇文章 0 订阅

计蒜客初赛5之前选了初赛3的题强行练手,确实这道题对思维的要求不低,要求转换思路,价值挺大。初赛5成功晋级后,将未完成的代码补完,完结此次初赛之旅。

 

 A. 腾讯课堂的物理实验

 

思路:这题明显是个模拟题,模拟两个小车的位置。不过,一开始准备写个程序专门判断小车位置,考虑到小车方向,时间,并单独处理碰撞和碰墙情况,由于还看存在半点碰撞和位置重合的情况,这样模拟十分复杂。

然而,如果换个思路,由于均为弹性碰撞,根据弹性碰撞性质(不要被题目的胡扯所干扰,大小相等方向相反只是巧合,正常情况应该为两车交换速度),碰后相当于a,b两车交换,而运动状态未发生任何变化,不影响两车之间的距离,因此,单独模拟两车运动,完全可以不用考虑碰撞

 

 

/*
Author:Owen_Q
*/

#include <bits/stdc++.h>

using namespace std;

int l;

int drive(int p,int t,int d)
{
    while(t--)
    {
        p += d;
        if(p==0||p==l)
        {
            d = d * (-1);
        }
    }
    return p;
}

int main()
{
    int ts,tt;
    while(scanf("%d%d%d",&l,&ts,&tt)!=EOF)
    {
        int a = drive(0,tt,1);
        int b = drive(l,tt-ts,-1);
        //cout << a << "*" << b << endl;
        int dis = (a-b);
        if(dis<0)
        {
            dis = dis * (-1);
        }
        printf("%d\n",dis);
    }
    return 0;
}

 

 

 B. 腾讯狼人杀(简单)

 

思路:这题以狼人杀为背景,长篇描述狼人杀,对于我这种不怎么玩这个游戏的人来说,莫名感到有点方,然而,读完题后才发现这题和狼人杀没有任何关系,只是一个组合匹配问题

注意到这题n仅为20,O(2^n)的复杂度完全没有问题,于是考虑到枚举所有组合方式,并用dfs实现以下就ok了,最后注意一下stl中stack的遍历

 

 

/*
Author:Owen_Q
*/

#include <bits/stdc++.h>

using namespace std;

const int maxn = 25;

int n,m;

double maxsum;

int w[maxn][maxn];

bool p[maxn];

stack<int> con;

void dfs(int t,int fig)
{
    if(t==n)
    {
        double money = con.size() * (2 * n - con.size());
        double sum = double(fig) / money;
        //cout << sum << "*"<<fig<<"*"<<money<<"*" <<maxsum << endl;
        if(sum > maxsum)
        {
            maxsum = sum;
        }
        return ;
    }
    if(!p[t])
    {
        dfs(t+1,fig);
    }
    stack <int> temp;
    while(!con.empty())
    {
        int i = con.top();
        fig += w[i][t];
        con.pop();
        temp.push(i);
    }
    while(!temp.empty())
    {
        int i = temp.top();
        temp.pop();
        con.push(i);
    }
    con.push(t);
    dfs(t+1,fig);
    con.pop();
    return ;
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(w,0,sizeof(w));
        while(!con.empty())
        {
            con.pop();
        }
        maxsum = 0;
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            scanf("%d",&w[u-1][v-1]);
            w[v-1][u-1] = w[u-1][v-1];
        }
        /*for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                cout << w[i][j]<< " ";
            }
            cout << endl;
        }*/
        for(int i=0;i<n;i++)
        {
            int temp;
            scanf("%d",&temp);
            if(temp == 1)
            {
                p[i] = true;
            }
            else
            {
                p[i] = false;
            }
        }
        dfs(0,0);
        printf("%.4f\n",maxsum);
    }
    return 0;
}

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值