2019牛客多校第5场总结
人生第一篇博客
在教练的教导下开启我人生的第一篇博客!由于懒得从第一场开始 那么就从最近的一场开始吧!
学写博客好麻烦我搞了好久才存在这些东西😂
那就进入正题。
一队友在地球的另一面与我们联机打比赛。想想这时差也是个狠人。
比赛开始我们在随便看题反正最后还是看榜做题搞啥战略。遂发现A题过的人巨多。 水题!!!
A 题意大概就是给你一个n,输出一个数x ,使得x每位数上的和为n的倍数,并且x也为n的倍数。看看n<=100,必有蹊跷。。。。一番讨论、改进我们得出结论。
算出n每位数的和sum输出LCM(sum,n)个n就完事!
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b)
{
return a*b/gcd(a,b);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,sum=0,x;
cin>>n;
x=n;
while(x)
{
sum+=x%10;
x/=10;
}
sum=lcm(n,sum);
for(int i=0;i<sum;i++)
{
cout<<n;
}
cout<<endl;
}
return 0;
}
签到即巅峰。。。。。于是我们因为太菜后面没有出题。
B题题意x(i)=ax(i-1)+bx(i-2)让你求x(n)
这个n大到可怕啊\(10^{10^6}\)
一看到x(i)=ax(i-1)+bx(i-2)这个递推式加上这时间这数据!!!这不就是学长教我们的矩阵快速幂吗!!!然而矩阵快速幂的专题还没有开始练。。。。。。die
于是开始抄找网上模版模仿之写出一堆bug。。。。我还是太菜了在一波瞎搞以后我终于搞定了n不大的时候算出答案了。。。n这么大怎么办。。。这才是这题的重点吧。此时另一队友因为太饿吃东西去了
tcl
开始在网上找x^n在n很大的情况下的快速幂。。。发现了一堆快速幂都不是我想要的😂就在这时我看到了希望的曙光。有一个大佬写了一个博客。
大佬的博客
没想到还有这种操作。
采用十进制式的快速幂
再看看这个n的范围太棒了这简直就是天意呀。套了一波矩阵过了样历
于是当然是充满自信的交题呀。。。。
结果T了
T!!!!!
不敢相信 优化到最后半个小时都没发现哪里导致了它的龟速。。。。
最后半小时看队友不太靠谱 没有思绪的亚子,我看了看G字符串题好像思路不对,于是签到结束😂。
赛后发现B题是真的可惜了!!!不过也学到了
到底T在哪


区别就在这!!!mod杀我!!!以后要注意mod的使用方式了它真是个不好对付的家伙。
B题代码就象征性放一下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
const int MAXN=2;
using namespace std;
typedef long long ll;
int mod;
ll number[1000005];
class Matrix
{
public:
ll m[MAXN][MAXN];
//二维数组存放矩阵
Matrix(){}
//对数组的初始化
void init(ll num[MAXN][MAXN])
{
for(ll i = 0 ; i < MAXN ; i++)
{
for(ll j = 0 ; j < MAXN ; j++)
{
m[i][j] = num[i][j];
}
}
}
//重载矩阵的乘法运算
friend Matrix operator*(Matrix &m1,Matrix&m2)
{
ll i, j, k;
Matrix temp;
for (i = 0; i < MAXN; i++)
{
for (j = 0; j < MAXN; j++)
{
temp.m[i][j]=0;
for(k=0;k<MAXN;k++)
{
temp.m[i][j]=(temp.m[i][j]+m1.m[i][k] * m2.m[k][j])%mod;
}
}
}
return temp;
}
//矩阵的快速幂
friend Matrix quick(Matrix M ,ll n)
{
Matrix tempans;
//初始化为单位矩阵
//初始化
for(ll i = 0 ; i < MAXN ; i++)
{
for(ll j = 0 ; j < MAXN ; j++)
{
if(i == j)
tempans.m[i][j] = 1;
else
tempans.m[i][j] = 0;
}
}
//快速幂(类似整数)
while(n)
{
if(n&1)
{
tempans = tempans * M;
}
//已经重载了*
n>>=1;
M = M * M;
}
return tempans;
}
friend Matrix quickpow(Matrix M ,char *n,ll len)
{
Matrix tempans;
//初始化为单位矩阵
//初始化
for(ll i = 0 ; i < MAXN ; i++)
{
for(ll j = 0 ; j < MAXN ; j++)
{
if(i == j)
tempans.m[i][j] = 1;
else
tempans.m[i][j] = 0;
}
}
//快速幂(类似整数)
while(len>0)
{
if(n[len-1]!='0')
{
ll s=n[len-1]-'0';
Matrix t;
t=quick(M,s);
tempans=tempans*t;
}
//已经重载了*
M=quick(M,10);
len--;
}
return tempans;
}
};
int main ()
{
int x0,x1,a,b;
ll num[MAXN][MAXN];
char s[1000005];
memset(num,0,sizeof(num));
Matrix p,po,ans;
scanf("%d%d%d%d %s%d",&x0,&x1,&a,&b,s,&mod);
num[0][0]=a;
num[0][1]=b;
num[1][0]=1;
num[1][1]=0;
p.init(num);
num[0][0]=x1;
num[1][0]=x0;
num[1][1]=0;
num[0][1]=0;
po.init(num);
int l=strlen(s)-1;
if(s[l]!='0')
s[l]--;
else
{
while(s[l]=='0')
{
s[l]='9';
l--;
}
s[l]--;
}
//puts(s);
// cout<<mod<<endl;
ans=quickpow(p,s,strlen(s));
ans=ans*po;
printf("%d\n",ans.m[0][0]%mod);
return 0;
}
赛后听学长说I题是到几何水题,题意大概就是在一个第一象限的矩形里求三个点,X,Y,Z的坐标,使得X到Y的距离为a,X到Z的距离为b,Y到Z的距离为c。
我的思路是以一个点为原点,对三条边排序,最小的边在x轴上(如果比矩形宽那么向上抬一些)那么另两条边的出两个圆的式子相交一算就算出来了另一个坐标。
主要的问题是。。。这谁是X,Y,Z我傻傻分不清啊先开始没读清楚题意。以为随便输出三个点就好了,没想到还得按顺序来的。
这使我暴躁了一会,到饭点了就打卡下班了。 后来又去打了会球。。。补题。。。还是先写博客吧!开始写博客之旅。。。。博客怎么这么难写。。。。再次暴躁。。。。
C题补完再更。可能思路有点麻烦???怪我没好好听学长讲题看来得学学几何知识。

人生啊!
我觉得我的代码没毛病啊!!!迷之自信
还是保存一波代码吧。虽然是错的,果然还是得按题解来吗😂
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
typedef long double lb;
const double eps=1e-7;
lb w,h;
lb a[3],ans[2][3],fina[2][3],b[3];
int flag=0;
lb dis(lb x1,lb y1,lb x2,lb y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void pan(lb xx,lb xy,lb yx,lb yy,lb zx,lb zy)
{
if(dis(xx,xy,yx,yy)-b[0]<eps&&dis(xx,xy,zx,zy)-b[1]<eps&&dis(yx,yy,zx,zy)-b[2]<eps)
{
if(xx<=w&&xy<=h&&yx<=w&&yy<=h&&zx<=w&&zy<=h)
{
fina[0][0]=xx;
fina[1][0]=xy;
fina[0][1]=yx;
fina[1][1]=yy;
fina[0][2]=zx;
fina[1][2]=zy;
printf("%.12Lf %.12Lf %.12Lf %.12Lf %.12Lf %.12Lf\n",fina[0][0],fina[1][0],fina[0][1],fina[1][1],fina[0][2],fina[1][2]);
flag=1;
return ;
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
lb x0,y0,X,Y;
flag=0;
scanf("%Lf%Lf%Lf%Lf%Lf",&w,&h,&a[0],&a[1],&a[2]);
for(int i=0;i<3;i++)
b[i]=a[i];
sort(a,a+3);
ans[0][0]=0.0;
ans[1][0]=0.0;
if(w>=a[1])
{
x0=a[0];
ans[1][1]=0.0;
ans[0][1]=a[0];
X=(x0*x0+a[2]*a[2]-a[1]*a[1])/(2*x0);
Y=sqrt(a[2]*a[2]-X*X);
}
else
{
lb t,A,B,C;
ans[0][1]=w;
ans[1][1]=sqrt(a[0]*a[0]-w*w);
x0=w;
y0=sqrt(a[0]*a[0]-w*w);
t=x0*x0+y0*y0+a[2]*a[2]-a[1]*a[1];
A=(1.0+(x0*x0)/(y0*y0));
B=(-x0*t)/(y0*y0);
C=(t*t/(4*y0*y0)-a[2]*a[2]);
X=(-B+sqrt(B*B-4*A*C))/(2*A);
Y=sqrt(a[2]*a[2]-X*X);
}
ans[0][2]=X;
ans[1][2]=Y;
if(!flag) pan(ans[0][0],ans[1][0],ans[0][1],ans[1][1],ans[0][2],ans[1][2]);
if(!flag) pan(ans[0][0],ans[1][0],ans[0][2],ans[1][2],ans[0][1],ans[1][1]);
if(!flag) pan(ans[0][1],ans[1][1],ans[0][0],ans[1][0],ans[0][2],ans[1][2]);
if(!flag) pan(ans[0][1],ans[1][1],ans[0][2],ans[1][2],ans[0][0],ans[1][0]);
if(!flag) pan(ans[0][2],ans[1][2],ans[0][0],ans[1][0],ans[0][1],ans[1][1]);
if(!flag) pan(ans[0][2],ans[1][2],ans[0][1],ans[1][1],ans[0][0],ans[1][0]);
if(!flag) pan(ans[1][0],ans[0][0],ans[1][1],ans[0][1],ans[1][2],ans[0][2]);
if(!flag) pan(ans[1][0],ans[0][0],ans[1][2],ans[0][2],ans[1][1],ans[0][1]);
if(!flag) pan(ans[1][1],ans[0][1],ans[1][0],ans[0][0],ans[1][2],ans[0][2]);
if(!flag) pan(ans[1][1],ans[0][1],ans[1][2],ans[0][2],ans[1][0],ans[0][0]);
if(!flag) pan(ans[1][2],ans[0][2],ans[1][0],ans[0][0],ans[1][1],ans[0][1]);
if(!flag) pan(ans[1][2],ans[0][2],ans[1][1],ans[0][1],ans[1][0],ans[0][0]);
}
return 0;
}
不知道错在哪。。。希望有一天能够领悟!

初级题都做不出来的我好菜啊。。。。
在观摩了一波别人的代码以后,终于ac了。差不多它是每种可能都算过去,碰到合适的就输出,算第三个坐标的时候运用了角度好像的确比我列式子快多了。
学到了
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
const double eps=1e-12;
double w,h,a,b,c;
struct poi
{
double x,y;
poi(){};
poi(double x,double y):x(x),y(y){}
}pp[3];
bool solve(double aa,double bb,double cc,int xx,int yy,int zz)
{
pp[xx]=poi(0.0,0.0);
double ang=acos((aa*aa+bb*bb-cc*cc)/(2.0*aa*bb));
if(aa<=w) pp[zz]=poi(aa,0.0);
else
{
pp[zz]=poi(w,sqrt(aa*aa-w*w));
ang+=acos(w/aa);
}
pp[yy]=poi(bb*cos(ang),bb*sin(ang));
if(0.0-eps<=pp[yy].x&&pp[yy].x<=w+eps&&0.0-eps<=pp[yy].y&&pp[yy].y<=h+eps)
{
printf("%.12f %.12f %.12f %.12f %.12f %.12f\n",pp[0].x,pp[0].y,pp[1].x,pp[1].y,pp[2].x,pp[2].y);
return 1;
}
return 0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lf%lf%lf%lf%lf",&w,&h,&a,&b,&c);
if(solve(a,b,c,0,2,1)) continue;
if(solve(a,c,b,1,2,0)) continue;
if(solve(b,a,c,0,1,2)) continue;
if(solve(b,c,a,2,1,0)) continue;
if(solve(c,a,b,1,0,2)) continue;
if(solve(c,b,a,2,0,1)) continue;
}
return 0;
}

浙公网安备 33010602011771号