A
题意
给出a,b两个数,我们可以进行两个操作:要么给a,b都加上1,要么都减1( min(a,b)>0 ),求gcd(a,b) 的最大值
思路
咋们老祖宗的定理,更相减损法,gcd(a,b)=gcd(a-b,b) (a>b), 因为b可以无限增大,但是a-b不变,所以说max(gcd(a,b)) = abs(a-b), 注意如果a==b,输出0 0
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
ll a,b;
scanf("%lld %lld",&a,&b);
if(a==b) printf("0 0\n");
else if(abs(a-b)==1) printf("1 0\n");
else
{
ll g=abs(a-b);
ll r=a%g;
//要对比是减更快,还是加更快
printf("%lld %lld\n",g,min(r,g-r));
}
}
return 0;
}
B
题意
给定一组数,a1,a2…an, 每次操作你可以对ai-1并且对aj+1,操作次数为任意次,最后使得这组数两两相减的绝对值之和最小。
思路
显然要使得两两相减的绝对值最小,那么直接平摊总和就是了,多余的放在最后几位,具体见代码
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5+9;
ll a[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
ll sum=0;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%lld",a+i);
sum+=a[i];
}
ll x=sum/n;
ll y=sum%n;
if(y==0) printf("0\n");
else
{
printf("%lld\n",(n-y)*y);
}
}
return 0;
}
C
题意
给定3张卡,他们被抽到的概率分别是c,m,p,给出一个系数v。如果抽到c, 那么c-min(c,v), m和p加上min(c,v)/2, 如果m已经为0了,则全部分给p,p+min(c,v)。 同理抽到m也是如此,直到抽到p结束,求抽取次数的期望值。
思路
这道题数据范围很小,直接爆搜就行了,要么抽c,要么抽m, 要么抽p,抽到p结束递归。注意:抽到c(m)时候,要看m©是否为0了
代码
#include<bits/stdc++.h>
using namespace std;
double ans;
const double eps=1e-6;
double v;
void dfs(double t,double c,double m,double p,double tmp)
{
if(p<eps)
{
ans+=(t*tmp);
return ;
}
if(c>eps)//选C
{
//看m是否为0,为0就不能再分配给它了
if(m>eps) dfs(t+1,c-min(c,v),m+min(c,v)/2,p+min(c,v)/2,tmp*c);
else dfs(t+1,c-min(c,v),m,p+min(c,v),tmp*c);
}
if(m>eps)
{
if(c>eps) dfs(t+1,c+min(m,v)/2,m-min(m,v),p+min(m,v)/2,tmp*m);
else dfs(t+1,c,m-min(m,v), p+min(m,v),tmp*m);
}
if(p>eps) dfs(t+1,c,v,0,tmp*p);
}
int main()
{
int t;
cin>>t;
while(t--)
{
double c,m,p;
ans=0;
scanf("%lf %lf %lf %lf",&c,&m,&p,&v);
dfs(0,c,m,p,1);
printf("%f\n",ans);
}
return 0;
}
D1
题意
这是一道交互题,系统存在一个密码x(0~n-1), 我们每次询问x的值是多少 y,如果猜对了,则系统返回1结束,否则x=x^y,系统返回0, 继续询问,要求最多询问n次猜对密码。
思路
我们每次猜错后密码都会变化,还可能>=n, 假设初始密码为x,现在的密码为y, 那么y=x^c的形式,c代表我前面猜测的一系列数的异或值,我们可以记录下c, 从0到n-1枚举x,一定可以在n次询问内找到答案
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,k;
scanf("%d%d",&n,&k);
int q;
int t=0;
for(int i=0; i<n; i++)
{
printf("%d\n",i^t);
fflush(stdout);
t^=(i^t);
scanf("%d",&q);
if(q==1) break;
}
}
return 0;
}
总结
奋斗中的蒟弱,如果你对本篇博客有好的建议或者批评,欢迎指出!