游记#2019浙大ACM

吐槽

9点开幕式了,奆佬杨子曰还没有来,打个电话,还在家里次饭emmm
话说上午热身赛神奇的T3,让chhokmah这样看遍了千万部番的人都束手无策啊
想不出来那些能A掉T3的人是多么的emmm
中饭在超市里解决,下面放一下本场比赛按顺序过掉的题目吧

T1-Extended Twin Composite Number

给定一个数n,让你找出2个数x,y满足x+n=y且x,y都是合数

解法

这道题是spj,那还要说什么。。。
奇数的x是9,偶数的x是4,木有毛病

ac代码

#include<bits/stdc++.h>
using namespace std; 
long long t,n;
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld",&n);
        if(n&1)printf("9 %d\n",n+9);
        else printf("4 %d\n",n+4);
    }
    return 0;
}

T2-Potion

给定两个序列,第一个为需求序列,第二个为已有序列
已有序列中的物品可以降级,求能否满足需求

解法

那就是线性从后往前扫一遍呗,这也是个签到题

ac代码

#include<bits/stdc++.h>
using namespace std; 
long long t,n,a[110],b[110],flg;
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld",&n),flg=1;
        for(long long i=1;i<=n;i++)scanf("%lld",&a[i]);
        for(long long i=1;i<=n;i++)scanf("%lld",&b[i]);
        for(long long i=n;i>=1;i--)
        {
            if(a[i]>b[i]){flg=0,puts("No");break;}
            b[i-1]+=b[i]-a[i];
        }
        if(flg)puts("Yes");
    }
    return 0;
}

T3-Postman

给定一个序列和一个数k,每次可以送k个或k个一下的物品,如果送完了就要回到原点(0)
问送完所有物品最少要走多少路程

解法

应该是一种贪心,将正负轴分开处理,因为每次经过原点都能补满
最后一次送完可以不回原点,所以最远的送完不回,其他以k个为一组,以最大值为贡献

ac代码

#include<bits/stdc++.h>
using namespace std; 
int t,n,k,x,a[100010],b[100010],cnta,cntb;
long long ans;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k),cnta=0,cntb=0,ans=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(x>0)a[++cnta]=x;
            else if(x<0)b[++cntb]=-x;
        }
        sort(a+1,a+1+cnta),sort(b+1,b+1+cntb);
        for(int i=cnta;i>=1;i-=k)ans+=a[i];
        for(int i=cntb;i>=1;i-=k)ans+=b[i];
        printf("%lld\n",ans*2-max(a[cnta],b[cntb]));
    }
    return 0;
}

T4-Thanks, TuSimple!

现在有n个男的m个女的及他们的身高
每个人有需求,需求分2种,需要比自己高的或比自己低的
问最多能配对多少组

解法

还是一个贪心,男高肯定和女低配,用两个指针扫,如果不满足就是女低的指针+1,另一种也是一样

ac代码

#include<bits/stdc++.h>
using namespace std; 
int t,n,m,x[100010],y[100010],a[100010],b[100010],c[100010],d[100010];
int cnta,cntb,cntc,cntd,ans,opt,p1,p2;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m),cnta=cntb=cntc=cntd=ans=0;
        for(int i=1;i<=n;i++)scanf("%d",&x[i]);
        for(int i=1;i<=m;i++)scanf("%d",&y[i]);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&opt);
            if(opt==1)a[++cnta]=x[i];
            else b[++cntb]=x[i];
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&opt);
            if(opt==1)c[++cntc]=y[i];
            else d[++cntd]=y[i];
        }
        sort(a+1,a+1+cnta),sort(b+1,b+1+cntb),sort(c+1,c+1+cntc),sort(d+1,d+1+cntd);
        p1=p2=1;
        while(p1<=cnta&&p2<=cntd)
            if(a[p1]<d[p2])ans++,p1++,p2++;
            else p2++;
        p1=p2=1;
        while(p1<=cntb&&p2<=cntc)
            if(b[p1]>c[p2])ans++,p1++,p2++;
            else p1++;
        printf("%d\n",ans);
    }
    return 0;
}

T5-Even Number Theory

给定一个数(高精度数),求小于它的偶数的累乘和的质因子中有几个2

解法

这道题耗了我们很久,因为一开始没看到那个even
转换一下,把这个数先除个2,就变成了一个n/2的阶乘中质因子有几个2再加上n/2
如果没有高精度,可以在log(n)时间内求解
加上高精度,就是log(n)*len(n),复杂度刚好

ac代码

因为懒得重打高精度,代码就不放了qwq
log(n)求解质因子中2的个数的方法就是下面这样的伪代码

while(n>0)n/=2,ans+=n;

T6-Robot Cleaner I

给一个图和一个操作序列,一个格子有三种状态,空地,墙壁和纸片
有6种操作,四种方向移动,剪纸片和什么都不做
每次进行的操作和当前格子和上下左右四个格子的状态有关,具体说一个三进制序列,在操作序列中映射出该三进制序列的值
问k次操作后能捡多少纸片(k<=1e18)

解法

看到那个(k<=1e18)了吗,看到之后都一脸懵,但是操作只有243种,n*m<=2000
所以一种可行的做法是矩阵哈希,这里用另一种做法,设上界qwq
和矩阵哈希的目的一样,都是为了让k到一定值后停下来,而不能模拟1e18次
设上界就比较玄学,设大了会T,设小了会WA,一个可以过的上界是2e6,剩下的步骤就是模拟了

ac代码

#include<bits/stdc++.h>
using namespace std; 
int t,n,m,x,y,mp[2010][2010],ans;
long long k;
char s[250],opt;
int f(int i,int j){return 81*mp[i][j]+27*mp[i-1][j]+9*mp[i+1][j]+3*mp[i][j-1]+mp[i][j+1];}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d%d%lld%s",&n,&m,&x,&y,&k,s),k=min(2000000ll,k),ans=0;
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%1d",&mp[i][j]);
        for(int i=1;i<=k;i++)
        {
            opt=s[f(x,y)];
            if(opt=='U'){if(mp[x-1][y]!=1)x--;}
            else if(opt=='D'){if(mp[x+1][y]!=1)x++;}
            else if(opt=='L'){if(mp[x][y-1]!=1)y--;}
            else if(opt=='R'){if(mp[x][y+1]!=1)y++;}
            else if(opt=='P'&&mp[x][y]==2)mp[x][y]=0,ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值