黑龙江农垦科技职业学院喜迎寒假多校联赛2 全题解

比赛链接:这里

OP

比赛原标题:黑龙江农垦科技职业学院喜迎寒假多校联赛2(快乐ak场)
//实际上并不快乐

A 数组截取

按字符读入之后转换为数字,比scanf快,学到了~
然后用滑窗来做//大概

#include <bits/stdc++.h>
using namespace std;
long long a[20000007],k;
int n;
inline long long read()
{
    long long x = 0;
    char ch = getchar();
    for( ; ch > '9' || ch < '0' ; ch = getchar());
    for( ; ch >= '0' && ch <= '9' ; ch = getchar()) x = (x << 3) + (x << 1) + (ch & 15);
    													/*      x10             %16    *///因为'0'是48
     return x;
}
int main()
{
    n = read() , k = read();
    for(int i = 1 ; i <= n ; i ++) a[i] = read();
    long long i,sum=0,m=0,l=1;
    i=1;
    for(i=1; i<=n; i++)
    {
        if(a[i]>k)
        {
            sum=0;
            l=i+1;
        }
        else
        {
            sum+=a[i];
            if(sum>k)
            {
                sum-=a[l];
                l++;
                while(sum>k&&i-l+1>=m)
                {
                    sum-=a[l];
                    l++;
                }
            }
            if(sum==k)
            {
                m=max(i-l+1,m);
            }
        }
    }
    if(m)
        printf("%lld",m);
    else printf("-1");
    return 0;
}

B 群友们在排列数字

深搜吧,每一层对应0~n-1的每个数,记得恢复现场。

#include <bits/stdc++.h>
using namespace std;
long long a[11]={0},n,k,sum,ten=1,cou=0,//a[i]表示第i位是否被占
b[11]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
//防止pow超时
void dfs(int num)
{
    if(num==n)//收束
    {
        if(sum%k==0)cou++;
        //printf("*%d\n",sum);
    }
    else
    {
        for(int i=0;i<n;i++)
        {
            if(a[i]==0)
            {
                a[i]=1;
                sum+=b[i]*num;
                dfs(num+1);
                sum-=b[i]*num;//恢复现场
                a[i]=0;
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&k);
    dfs(0);
    if(cou)printf("%lld",cou);
    else printf("-1");
    return 0;
}

C gg查成绩

区间和~
第 k 位存下1~ k 的和,求[ i , j ]时输出 a[ j ] - a[ i - 1 ]就好了

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    static int a[1000006]={0};
    int n,m,i,j;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        a[i]+=a[i-1];
    }
    while(m--)
    {
        scanf("%d%d",&i,&j);
        printf("%d\n",a[j]-a[i-1]);
    }
    return 0;
}

D issue与lifehappy给学生分组

中心是二分
类似题可以参考:NEFU OJ-1211 卖古董NEFU OJ-1708 书的复制

注意二分的临界和取整!

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    static unsigned long long a[1000006];
    int n,m;
    unsigned long long l=1e11,r=1e19;
    scanf("%d%d",&n,&m);
    //printf("%d\n",n);
    for(unsigned long long int i=1;i<=n;i++)
    {
        scanf("%llu",&a[i]);
        if(a[i]<l)l=a[i];
    }
    while(l<r)
    {
        unsigned long long mid=l+r>>1;
        unsigned long long team=1,num=0;
        for(unsigned long long int i=1;i<=n;i++)
        {
            if(num+a[i]<=mid)
                num+=a[i];
            else team++,num=a[i];
        }
        if(team<=m)r=mid;
        else l=mid+1;
        //printf("%u %u\n",mid,team);
    }
    printf("%llu",l);
    return 0;
}

E 删删删越小越好

因为总位数是固定的,已知删去位数即已知剩余位数,在原数中有序找到剩余位数个 数,并使最小就好了。使其最小就是对于每一位,在可以寻找的区间内找到最小数。
注意寻找区间的范围

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    static char a[20000007];
    int n,i,j,pok=0;
    i=0;
    while(~scanf("%c",&a[i])&&a[i++]!='\n');
    a[i-1]=0;
    scanf("%d",&n);
    int m=strlen(a);
    n=m-n;
    //printf("%d",n);
    int l=0;
    while(n--)
    {
        char ma='9'+1;
        int mark=0;
        for(;l+n<=m-1&&ma!='0';l++)//如果找到0,就不需要再找了,没有比0更小的了&l+n<=m-1即为可寻找区间
        {
            if(a[l]<ma)ma=a[l],mark=l;
        }
        if(a[mark]!='0')pok=1;
        if(pok)
        printf("%c",ma);
        l=mark+1;
    }
    if(!pok)printf("0");
    return 0;
}

F happy的异或运算

异或可以看成在二进制下进行的不进位加法。
若区间右端点为n,则必存在一m满足在有效位数上(不含前导零)m==~n(即按位取反)且m<n。因为n的最高有效位必为1,m的此位即为0,故m<n。
两数异或运算后即为111…11。

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    long long g;
    scanf("%lld",&g);
    long long int i=1;
    while(g)//注
    {
        g>>=1;
        i++;
    }
    i--;
    cout<<(long long)pow(2,i)-1;
    return 0;
}

注:这里用for(two=1;two<g;two*=2);会超时

G Alan%%%

字符串处理,闹心~

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    int n,i,f,sum=0;
    //char a[1003];
    string a;
    cin>>n;
    getchar();
    while(n--)
    {
 
        getline(cin,a);
        int cou=0,cou1=0;
        f=0;
        for(i=0;a[i];i++)
        {
            if(a[i]==' ')continue;
            if(f==1)
            {
                if(a[i]=='l')f++;
                else f=0;
            }
            else if(f==2)
            {
                if(a[i]=='a')f++;
                else f=0;
            }
            else if(f==3)
            {
                if(a[i]=='n')cou1=1,f=0;
                else f=0;
            }
            if(a[i]=='%')cou++;
            else if(a[i]=='A')f=1;
        }
        //printf("%d %d\n",cou,cou1);
        sum+=cou*cou1;
    }
    cout<<sum;
    return 0;
}

%%%

H&I cg写项目

结构体排序,自定义cmp~
两题代码一粘就行

#include <bits/stdc++.h>
using namespace std;
struct
dataa{
    char n[25],m[25],x[25],h[25];
    int num;
}use[1000000];
bool cmp(dataa a,dataa b)
{
    if(strlen(a.n)==strlen(b.n))
    {
        int s=strcmp(a.n,b.n);
        if(!s)
        {
            return a.num<b.num;//注
        }
        else if(s>0)return 0;
        else return 1;
    }
    else return strlen(a.n)<strlen(b.n);
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        use[i].num=i;
        scanf("%s",use[i].n);
        scanf("%s",use[i].m);
        scanf("%s",use[i].x);
        scanf("%s",use[i].h);
    }sort(use+1,use+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        printf("%s ",use[i].n);
        printf("%s ",use[i].m);
        printf("%s ",use[i].x);
        printf("%s\n",use[i].h);
    }
    return 0;
}

注:这里写a<b会报错,因为a,b是类似于迭代器。
//我怎么会这么想…

J 比赛开始了清楚姐姐喊了一句:签到了签到了

签到了签到了

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    int n,m=100000,i,j,mark;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&j);
        if(j<m){m=j;mark=i;}
    }
        printf("%d",mark);
    return 0;
}

ED

还是…蛮快乐的……

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值