题目链接:Distance and Axis
题意:在ox轴上,给出点A的横坐标x,你可以向左或右移动点A(x+1/x-1),问你最小移动A的次数,以使得可以在ox轴上找到B点位置,B点满足从O到B的距离与从A到B的距离之间的绝对差等于k。
题解:
先特判下:
if(k==0) { if(n%2) printf("1 "); else printf("0 "); } else if(k>=n) { printf("%d ",k-n); }
对于A点坐标x,最终要移动到哪里,x满足x=2*min(OB,AB)+k
那么枚举OB长度就行,找到距离x点最近那个点就行
为什么不枚举AB,因为枚举它们两个谁,代码都一样
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stack> 2 #include<queue> 3 #include<map> 4 #include<cstdio> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 #include<vector> 9 #define fi first 10 #define se second 11 #define pb push_back 12 using namespace std; 13 typedef long long ll; 14 const int maxn=2000+10; 15 const int mod=1e9+7; 16 const double eps=1e-8; 17 const int INF = 0x3f3f3f3f; 18 int main() 19 { 20 int t; 21 scanf("%d",&t); 22 while(t--) 23 { 24 int n,k; 25 scanf("%d%d",&n,&k); 26 if(k==0) 27 { 28 if(n%2) 29 printf("1 "); 30 else printf("0 "); 31 } 32 else if(k>=n) 33 { 34 printf("%d ",k-n); 35 } 36 else 37 { //k+2min(OB,AB) 38 int l=0,r=n,mid,minn=INF; 39 while(l<=r) 40 { 41 mid=(l+r)>>1; 42 int ans=mid*2+k; 43 if(ans>n) 44 { 45 r=mid-1; 46 minn=min(minn,ans-n); 47 } 48 else 49 { 50 l=mid+1; 51 minn=min(minn,n-ans); 52 } 53 } 54 printf("%d ",minn); 55 } 56 } 57 return 0; 58 }
题目链接:Ternary Sequence
题意:
你有两个序列a,b。序列是由0,1,2构成。给你x1,y1,z1表示a序列中0,1,2的数量,给你x2,y2,z2表示b序列中0,1,2的数量,
如果你构造的a,b序列中,ai==bi,那么结果+0,如果ai>bi,结果加ai*bi。如果ai<bi,结果减ai*bi
让你输出最大结果
题解:
结果想尽可能大,那就先让z1的2和y2的1结合,那么结果这个时候为2*min(z1,y2)
然后如果结果变小,肯定是z2的2和y1的1结合了,那么我们先让z2和x1结合,再和进行完上面操作的z2结合,最后结果减去剩余的z2*2
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stack> 2 #include<queue> 3 #include<map> 4 #include<cstdio> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 #include<vector> 9 #define fi first 10 #define se second 11 #define pb push_back 12 using namespace std; 13 typedef long long ll; 14 const int maxn=2000+10; 15 const int mod=1e9+7; 16 const double eps=1e-8; 17 const int INF = 0x3f3f3f3f; 18 int main() 19 { 20 int t; 21 scanf("%d",&t); 22 while(t--) 23 { 24 int x1,x2,y1,y2,z1,z2; 25 scanf("%d%d%d",&x1,&y1,&z1); 26 scanf("%d%d%d",&x2,&y2,&z2); 27 int sum=0,ans=min(z1,y2); 28 z1-=ans; 29 y2-=ans; 30 sum=sum+ans*2; 31 32 ans=min(x1,z2); 33 x1-=ans; 34 z2-=ans; 35 36 if(z2) 37 { 38 ans=min(z1,z2); 39 z1-=ans; 40 z2-=ans; 41 if(z2) 42 { 43 sum=sum-z2*2; 44 } 45 } 46 printf("%d ",sum); 47 } 48 return 0; 49 }
题目链接:Mere Array
题意:
给你一个序列,如果gcd(ai,aj)==序列中的最小值,那么ai和aj可以交换,问你最后能不能把原序列变成一个非递减序列
题解:
我们设序列最小值为minn,我们把可以被minn整除的数找出来,那么剩下数的位置是不能改变的
这个时候我们对原序列sort从小到大排序,判断一下我们要构成的最终序列中,那么不能被minn整除的数的位置改变了没有
如果改变了,那就输出NO,否则YES
毕竟对于可以被minn整除的数来说,它们的位置总是可以通过minn来达到间接互换
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stack> 2 #include<queue> 3 #include<map> 4 #include<cstdio> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 #include<vector> 9 #define fi first 10 #define se second 11 #define pb push_back 12 using namespace std; 13 typedef long long ll; 14 const int maxn=1e5+10; 15 const int mod=1e9+7; 16 const double eps=1e-8; 17 const int INF = 0x3f3f3f3f; 18 ll v[maxn],w[maxn]; 19 int main() 20 { 21 ll t; 22 scanf("%lld",&t); 23 while(t--) 24 { 25 ll n,minn=INF,flag=0; 26 scanf("%lld",&n); 27 for(ll i=1;i<=n;++i) 28 scanf("%lld",&v[i]),w[i]=v[i],minn=min(minn,v[i]); 29 sort(v+1,v+1+n); 30 ll last=0; 31 for(ll i=1;i<=n;++i) 32 { 33 if(v[i]%minn==0) continue; 34 if(v[i]%minn && v[i]==w[i] && last<=w[i]) last=w[i]; 35 else 36 { 37 flag=1; 38 break; 39 } 40 } 41 if(flag) printf("NO "); 42 else printf("YES "); 43 } 44 return 0; 45 }