比赛的时候没做出C来,是个简单的二分,有点可惜。后来用二分法做了一下也做出来了,感觉是能力范围之内的题…
A. Distance
有A.B.C三个坐标点,A为(0,0),给出B的坐标点,要求满足两个式子:
d(A,C)=d(A,B)/2 d(B,C)=d(A,B)/2 如果能找到C就输出任意一个满足答案的坐标,如果不能找到则输出-1。
在编程中除特殊情况外尽量不要出现除法,随时可能会导致错误。把2挪到式子左边比较好,坐标的范围也很小,直接遍历查找就可以了。
#includeusing namespace std; typedef long long ll; int main() { int i,n,t,ans=0,j,x,y,u,w,o,p; cin>>t; while(t--) { p=0; cin>>x>>y; for(i=0;i<=50;i++) { for(j=0;j<=50;j++) { u=x-0+y-0; w=abs(i-0)+abs(j-0); o=abs(i-x)+abs(j-y); if(u==2*w&&u==2*o) {p=1;break;} } if(p==1) break; } if(p==1) cout< B. Special Permutation
设定序列为1-n,给出序列长度(偶数),将序列平分为左右两半,给出左半序列最小值a,右半序列最大值b,判断是否有这样的序列,如果没有则输出-1,有则任意输出一个满足答案的序列。
首先要判断是否存在这样的序列,给出a,所以要把左边剩下的部分全部填上比a大的数,但是a可能比较大使得左边a并不是最小值,这样就不会有这个序列,右边同理。满足a为最小值b为最大值后从大到小往左、右两个序列里赋值,最后输出序列即可。#includeusing namespace std; typedef long long ll; int main() { int i,n,t,a,b,sum,num; cin>>t; while(t--) { sum=0;num=0; cin>>n>>a>>b; int p=n; int c[n]; int aver=n/2; for(i=1;i<=n;i++) { if(i>a) sum++; } for(i=1;i<=n;i++) { if(i>b) num++; } if(a>b) num--; if(aaver-1) {cout<<"-1"< C. Chat Ban
以上为发送三条消息产生的图形,k为3,总数为9
现在一个人想要发送消息,但是发送过多条的图形会被管理员限制,给出k和限制数x(一个图形算一个,不能发送比x还多的图形),求它最多能发送多少条消息(一行算一条,哪怕这行只发送出一个图形,也算发送出了这条消息),求这个人最多能发送出多少条消息。
听说可以用纯数学,但我看到可以用二分来做立马感觉可以试试。首先可以将大图分为两个等差数列,等差数列求和的公式不用说了吧。接下来就是查找这个和的位置了,这简直就是直接套二分模板,我把两个等差数列分情况列了两个二分,好像大佬用一个二分就行了。因为ans开的不够大,还是导致我wr了几次。
#includeusing namespace std; typedef long long ll; int main(){ ll t,l,r,mid; cin>>t; while(t--){ ll ans=10000000000; ll k,x; cin>>k>>x; if(x>=k*k) {cout<<2*k-1< =x) { // 只要消息总数比限制数大就要减少消息的条数 r=mid-1; ans=min(ans,mid); } else l=mid+1; // 消息总数比限制数小我们就可以增加消息的条数 } if(x<=k*(k+1)/2){ cout< k*(k+1)/2&&x =x) { r=mid-1; ans=min(ans,mid); } else l=mid+1; } cout<



