2024牛客寒假算法基础集训营1(B、C、E、L)

B.关鸡

原题链接:B-关鸡_2024牛客寒假算法基础集训营1 (nowcoder.com)

2024牛客寒假算法基础集训营1(B、C、E、L)_第1张图片

解题思路:

如图所示,红色部分是满足关鸡的最低要求为3。

其次,黄色部分是指着火点位于同一列或者列数相差1时满足。

重点考虑的是鸡的周围有没有着火点。

代码如下:

#include 
#include 
#define int long long
#define endl '\n'
using namespace std;
struct card{int r,c;}s[100005];
int cmp(card a,card b)
{
    return a.c>t;
    while(t--)
    {
        memset(s,0,sizeof(s));
        int x=0,sum=3,y=0,q=0;
        cin>>n;
        for(int i=1;i<=n;i++)
            {cin>>s[i].r>>s[i].c;
            if(s[i].r==2&&s[i].c==0)q=1,sum--;
            else if(s[i].r==1&&s[i].c==-1)sum--;
            else if(s[i].r==1&&s[i].c==1)sum--;}
        sort(s+1,s+n+1,cmp);
        if(s[1].c<0)x=1;
        if(s[n].c>=0)y=1;
        for(int i=2;i<=n;i++)
            {if(x!=2)
            {if(s[i].c==s[i-1].c&&s[i].c<0)x=2;
            else if(s[i].c==s[i-1].c+1&&s[i-1].c<0&&s[i].r!=s[i-1].r)x=2;}
             if(y!=2)
           {if(s[i].c==s[i-1].c&&s[i].c>0)y=2;
            else if(s[i].c==s[i-1].c+1&&s[i].c>0&&s[i].r!=s[i-1].r)y=2;}
            if(x==2&&y==2)break;}
        if((x==2||y==2)&&q==1&&sum!=0)sum=1;
        sum=min(sum,4-x-y);
        cout<

C.按闹分配

原题链接:C-按闹分配_2024牛客寒假算法基础集训营1 (nowcoder.com)

解题思路:假设鸡要插第i个人的队,则前面每个人的时间不变,后面每个人办事的时间都需要再加上鸡办事所需要的时间,从而增加的总时间=(n-i)*  tc 。

代码如下:

#include 
#include 
#define int long long
#define endl '\n'
using namespace std;
signed main()
{   
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,q,c,t[1000005],s[1000005]={0},m;
    cin>>n>>q>>c;
    for(int i=1;i<=n;i++)
        cin>>t[i];
    sort(t+1,t+n+1);        
    for(int i=1;i<=n;i++)
        s[i]=s[i-1]+t[i];    //从小到大排序,求出Smin
    while(q--)
    {
        cin>>m;
        int a=min(n,m/c);    //求出最多能允许几个人插队,用min的作用是防止m/c超出n的范围
        cout<

E、本题又主要考察了贪心

原题链接:E-本题又主要考察了贪心_2024牛客寒假算法基础集训营1 (nowcoder.com)

解题思路:(此题用贪心应该是做不起来的,亏我想了半天。)

由于此题数据范围很小,可以考虑使用dfs,对于每一场比赛分三种情况讨论,第一个人赢、第二个人赢和平局,最终会形成一个树状结构,取最后一次比赛后的最小值即可。

#include 
#include 
#define int long long
#define endl '\n'
using namespace std;
int t,n,m,sum,a[12],u[12],v[12];
void dfs(int s)
{
    if(s>m)
    {
        int k=1;
        for(int i=1;i<=n;i++)
            if(a[i]>a[1])k++;
        sum=min(sum,k);
        return;
    }
    a[u[s]]+=3; //第一个人赢
    dfs(s+1);
    a[u[s]]-=3; //返回上一次比赛的结果,进行下一次讨论

    a[v[s]]+=3; //第二个人赢
    dfs(s+1);
    a[v[s]]-=3;

    a[u[s]]+=1; //平局
    a[v[s]]+=1;
    dfs(s+1);
    a[u[s]]-=1;
    a[v[s]]-=1;
}
void solve()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=m;i++)
        cin>>u[i]>>v[i];
    sum=99;    //最开始要保证sum一定要大于k
    dfs(1);
    cout<>t;
    while(t--)
    {
        solve();
    }
 	return 0;
}

L.要有光

原题链接:L-要有光_2024牛客寒假算法基础集训营1 (nowcoder.com)

解题思路:运用假设,如果太阳无限高,相应的阴影面积就无限小,因此随着太阳的升高阴影面积逐渐减小,即太阳位于地面时阴影面积最大,是一个等腰梯形。(仅是猜想,证明不会)

#include 
#include 
#define int long long
#define endl '\n'
using namespace std;
signed main()
{   ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t,c,d,h,w,s;
    cin>>t;
    while(t--)
    {
        cin>>c>>d>>h>>w;
        s=3*w*c;
        cout<

你可能感兴趣的:(算法)