吐槽
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;
}