台州学院ACM集训队月赛(元旦场)

比赛地址戳这里

1001 : 数学题:

求极限:
在这里插入图片描述

在这里插入图片描述

1002 : maomeng的成就

题解:
对于某一个物品i,我们可以选择他的第一个成就,或者选择第二个成就,又或者不选,这样我们就可以使用dfs,来遍历所有情况。时间复杂度为O(3^10).

#include<bits/stdc++.h>
using namespace std;
const int N=10+5,mod=1e9+7;
typedef long long LL;
int tt[N],m[N],T[N],M[N];
int n,t,ans=0;
void dfs(int i,int time,int sum)
{
    //cout<<time<<endl;
    if(time<=t)//如果时间小于t就比较。
    {
        ans=max(sum,ans);
    }
    if(i>n)return;//超过物品数量就返回。
    dfs(i+1,time+tt[i],sum+m[i]);
    dfs(i+1,time+T[i],sum+M[i]);
    dfs(i+1,time,sum);
}
void solve()
{

    scanf("%d %d",&n,&t);
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d %d %d",&tt[i],&m[i],&T[i],&M[i]);
    }
    dfs(1,0,0);
    printf("%d",ans);
}
int main()
{
    solve();
}

1003 : maomeng的boss战

在一秒内我们收到的伤害为2n,那么我们就可以先将总血量除掉2n,那么剩下的血量如果大于等于n,那么就表示小z可以扛过这一秒,反之则不行。

#include<bits/stdc++.h>
using namespace std;
const int N=10+5,mod=1e9+7;
typedef long long LL;
int n,m;
void solve()
{
    m-=1;//注意血量先减一
    int s=2*n;
    int cnt=m/2/n,re=m%(2*n);
    if(re>=n)cnt++;
    printf("%d\n",cnt);
}
int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        solve();
    }
}

1004 : 竞选总统:

题解:
记录一下最高票数和平均票数,如果最高票数小于平均票数,则需要(平均票数-已有票数,否则,若最高票数无并列,则小于最高票数的需要(最高票数+1-已有票数),等于的要0票。若最高票数有并列,则需要(最高票数+1-已有票数。

#include <bits/stdc++.h>
using namespace std;

const int N = 2000;

int n;
int a[N];
int main()
{
    cin >> n;
    int m = -1,cnt = 0;
    for(int i = 1; i <= n; i ++)
    {
        scanf("%d",&a[i]);
        if(a[i] == m) cnt ++;
        if(a[i] > m) m = a[i],cnt = 1;
    }
    for(int i = 1; i <= n; i ++)
    {
        if(a[i] < m) printf("%d",m - a[i] + 1);
        else if(a[i] == m)
        {
            if(cnt > 1) printf("1");
            else printf("0");
        }
        if(i != n) printf(" ");
    }
    return(0);
}

1005 : maomeng的不知道什么东西

题解:
ps.数据可能弱了
首先对于一个数a[i],在他左边有几个比他小的数我们记作l[i]。
对于一个数a[i],在他右边有几个比他小的数我们记作r[i]。
对于每一个数a[i],他在答案里的贡献就是了l[i]*r[i]*a[i]。
为什是这样呢。因为相当于在他的左区域任意选一个点,右区域也任意选一个点,那么这个连续字串的值都为a[i]。
这样我们就可以使用单调栈(不会的先了解一下)在O(n)的时间复杂度里求出l[i]和r[i]了。

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5,mod=1e9+7;
typedef long long LL;
LL a[N],l[N],r[N];
struct node{
    LL x,pos;
};
void solve()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    a[0]=a[n+1]=1e9;
    stack<node>st;
    st.push({a[0],0});
    for(int i=1;i<=n;i++)
    {
        if(!st.empty())
        {
            while(st.top().x<=a[i])st.pop();
        }
        int x=st.top().x,pos=st.top().pos;
        l[i]=pos+1;
        st.push({a[i],i});
    }
    while(!st.empty())st.pop();
    st.push({a[n+1],n+1});
    for(int i=n;i>=1;i--)
    {
        if(!st.empty())
        {
            while(st.top().x<a[i])st.pop();
        }
        int x=st.top().x,pos=st.top().pos;
        r[i]=pos-1;
        st.push({a[i],i});
    }
    LL ans=0;
    for(int i=1;i<=n;i++)
    {
        LL L=(i-l[i]+1),R=(r[i]-i+1);
        ans=((L*R*a[i])%mod+ans)%mod;
    }
    printf("%lld",ans);
}
int main()
{
    solve();
}

1006 : maomeng请了外援

题解:
经过观察(真的。我们可以发现只要将前两行的三个字母确定了,那么n阶金字塔就确定了。
我们暴力模拟出六种情况的金字塔,和原金字塔进行比较,筛选出重合度最高的然后就可以了。

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5,mod=1e9+7;
typedef long long LL;
int a[N][N];
int t[7][N][N];
int n;
void st(int x,int y,int id)
{
    t[id][x][y]=6-(t[id][x-1][y]+t[id][x-1][y-1]);
}
void solve()
{

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        getchar();
        for(int j=1;j<=i;j++)
        {
            char p;
            scanf("%c",&p);
            if(p=='G')a[i][j]=1;
            if(p=='R')a[i][j]=2;
            if(p=='B')a[i][j]=3;
        }
    }
    t[1][1][1]=1;t[1][2][1]=2;t[1][2][2]=3;
    t[2][1][1]=1;t[2][2][1]=3;t[2][2][2]=2;
    t[3][1][1]=2;t[3][2][1]=1;t[3][2][2]=3;
    t[4][1][1]=2;t[4][2][1]=3;t[4][2][2]=1;
    t[5][1][1]=3;t[5][2][1]=1;t[5][2][2]=2;
    t[6][1][1]=3;t[6][2][1]=2;t[6][2][2]=1;
    for(int i=1;i<=6;i++)
    {
        for(int j=3;j<=n;j++)
        {
            for(int k=2;k<n;k++)st(j,k,i);
            //注意特判每行的第一个和第最后一个
            t[i][j][1]=6-(t[i][j-1][1]+t[i][j][2]);
            t[i][j][j]=6-(t[i][j-1][j-1]+t[i][j][j-1]);
        }
    }
    int res=0;
    for(int i=1;i<=6;i++)
    {
        int ans=0;
        for(int j=1;j<=n;j++)
        {
            for(int k=1;k<=j;k++)
            {
                if (t[i][j][k] == a[j][k])ans++;
            }
        }
        res=max(ans,res);
    }
    printf("%d",n*(n+1)/2-res);
}
int main()
{
    solve();
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值