Test 2022.09.28
今天好像是做的牛客上面的题
T1 三元一次方程
题意:给出\(ax+by+cz=d中的a,b,c,d\),求是否存在一组整数\(x,y,z\)使得等式成立
分析:
一拿到这道题打了打表发现当\(gcd(a,b,c)|d\)的时候就一定存在,证明了一下,就是用裴蜀定理换元就行,最后可以延展到\(n\)元一次方程,实际上最后得到的有解条件都是一样的,所以就成功\(30pts\)了
真正的细节:
实际上在计算\(gcd\)的时候会调用模运算,这要求我们的模数是不能为\(0\)的,然而我没有考虑这一点,所以掉了很多分,要打满也很简单,特判一下\(2^3=8\)种情况就行了
Code
点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
long long gcd(long long x,long long y){return x%y==0?y:gcd(y,x%y);}
int main()
{
// freopen("niuniufx.in","r",stdin);
// freopen("niuniufx.out","w",stdout);
long long T;
scanf("%lld",&T);
long long a,b,c,d;
while(T--)
{
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
if(a==0&&b==0&&c==0)
{
if(d==0)printf("YES\n");
else printf("NO\n");
}
else if(a!=0&&b==0&&c==0)
{
if(d%a==0){printf("YES\n");}
else printf("NO\n");
}
else if(a==0&&b!=0&&c==0)
{
if(d%b==0){printf("YES\n");}
else printf("NO\n");
}
else if(a==0&&b==0&&c!=0)
{
if(d%c==0){printf("YES\n");}
else printf("NO\n");
}
else if(a!=0&&b!=0&&c==0)
{
if(d%gcd(a,b)==0){printf("YES\n");}
else printf("NO\n");
}
else if(a!=0&&b==0&&c!=0)
{
if(d%gcd(a,c)==0){printf("YES\n");}
else printf("NO\n");
}
else if(a==0&&b!=0&&c!=0)
{
if(d%gcd(b,c)==0){printf("YES\n");}
else printf("NO\n");
}
else
{
long long tmp=gcd(gcd(a,b),c);
if(d%tmp==0)printf("YES\n");
else printf("NO\n");
}
}
return 0;
}
T2 猜球游戏(很好的思维题)
题意
就是给出\(n\)个操作,每个操作交换\(0-9\)中\(l,r\)下标的两个数字,\(m\)个询问,每次询问做出\(u-v\)的操作,问操作最后的序列是什么
心路历程
弱智的我一眼就想到了前缀和,因为数据范围太大了,只能支持\(O(1)\)的查询,但是我还是只停留在了前缀和最浅的层面———简单的对数值进行统计,然而前缀和完全可以是很多种抽象的概念,可以是各种事件带来的影响。
正解
对于当前这道题,单单只用前缀和来感性理解,我相信是没有人能够一下就定义出来所谓前缀和到底是代表了啥的(神犇除外),就比如说这道题用来消除影响的数组,我这里提供一种经过了努力的思考,得出的一种对于正常人来说还比价容易理解的思路,\(respect!\)
先上图片
对于我举例的这个序列,我们假设这一次询问输入的\(L_i,R_i\)分别是\(3,5\),那么从\(1-5\)的递推后第五次结束得到的答案已经写在左边了,但这肯定不是我们需要输出的。
问题是我们该如何得到实际询问的时候应该输出的答案呢?已经画在图片上面了,假设天然存在\(zero-five\)六个容器,然后把当前的数字放进去再做交换操作,那么无论是对于我们在递推时,还是在询问中,交换盒子的操作一定是等效的,不会有不同的地方,只是盒子里面的数字不同罢了。
那么聪明的你一定会发现,询问中的操作相当于是把\(0-5\)的数字分别放进了\(zero-five\)的盒子里面,我们只要建立递推时盒子里的序列和\(0-5\)的映射关系,最后在递推结果的基础上,用映射的方式输出就能做到接近\(O(1)\)查询了,就像下图一样
是不是很简单很容易理解?
Code
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
inline void read(int &x)
{
x=0;int f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')f=-1;
c=getchar();
}
while('0'<=c&&c<='9')
{
x=(x<<1)+(x<<3)+(c^48);
c=getchar();
}
x*=f;
}
int a[maxn][15]/*a(i,j)是第i次j位置对应的值*/,inv[maxn][15]/*inv(i,j)第i次要消除影响,对应的值j应该变成的值*/,tmp[15];
int ans[15];
int main()
{
int n,m;
read(n),read(m);
int l,r;
for(int i=0;i<=9;i++)a[0][i]=inv[0][i]=i;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=9;j++)a[i][j]=a[i-1][j];
read(l),read(r);
swap(a[i][l],a[i][r]);
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<=9;j++)tmp[a[i][j]]=j;
for(int j=0;j<=9;j++)inv[i][j]=tmp[j];
}
while(m--)
{
read(l),read(r);
for(int j=0;j<=9;j++)printf("%d ",inv[l-1][a[r][j]]);
printf("\n");
}
}
暂时鸽掉的T3,T4
本文来自博客园,作者:Hanggoash,转载请注明原文链接:https://www.cnblogs.com/Hanggoash/p/16739432.html