• Daily Practice:Codeforces Round #812 (Div. 2)(A~D)


    VP*n

    A. Traveling Salesman Problem

    给出若干个点的坐标,求经过所有点所需要最短距离。

    思路:找四个方向上最外侧的点,其实最终的距离一定是最外侧点组成的矩形的周长,具体可以看样例给的图片。注意最小值是与0的距离,因为存在在x轴上和y轴上的点。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int N=105;
    4. int t,n;
    5. int main(){
    6. std::ios::sync_with_stdio(false);
    7. std::cin.tie(0);
    8. std::cout.tie(0);
    9. std::cin>>t;
    10. while(t--){
    11. std::cin>>n;
    12. int minx=0,miny=0,maxx=0,maxy=0;
    13. for(int i=1;i<=n;i++){
    14. int x,y;
    15. std::cin>>x>>y;
    16. if(y==0){
    17. if(x>0) maxx=std::max(maxx,x);
    18. else minx=std::min(minx,x);
    19. }
    20. else{
    21. if(y>0) maxy=std::max(maxy,y);
    22. else miny=std::min(miny,y);
    23. }
    24. }
    25. std::cout<<2*(maxx-minx)+2*(maxy-miny)<<'\n';
    26. }
    27. return 0;
    28. }

    B. Optimal Reduction

    对于一个数组,它的值是通过以下操作得到全0数组的操作数:选择一个连续区间,将其中的每个数-1。对于给出的数组,若存在一个新的排列顺序使得它的值小于原数组,输出no,否则输出yes。

    思路:使得较大数不能减少操作次数的原因是有较小数截断。所以只要存在一个数两侧都有大于它的数,那一定存在更少的操作次数。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int N=1e5+5;
    4. int t,n;
    5. int a[N],left[N],right[N];
    6. int main(){
    7. std::ios::sync_with_stdio(false);
    8. std::cin.tie(0);
    9. std::cout.tie(0);
    10. std::cin>>t;
    11. while(t--){
    12. std::cin>>n;
    13. for(int i=1;i<=n;i++){
    14. std::cin>>a[i];
    15. }
    16. memset(left,0,sizeof(left));
    17. memset(right,0,sizeof(right));
    18. for(int i=1;i<=n;i++){
    19. left[i]=std::max(left[i-1],a[i]);
    20. }
    21. for(int i=n;i>=1;i--){
    22. right[i]=std::max(right[i+1],a[i]);
    23. }
    24. bool flag=true;
    25. for(int i=2;i
    26. if(left[i]>a[i]&&right[i]>a[i]){
    27. flag=false;
    28. break;
    29. }
    30. }
    31. std::cout<<(flag?"YES":"NO")<<'\n';
    32. }
    33. return 0;
    34. }

     C. Build Permutation

    给出0到n-1,以及相同的下标,构造一个数组,使得元素和下标之和是完全平方数

    思路:举个例子先:

    1. 7
    2. 1 0 2 6 5 4 3

     这样后一半都是9,前一半是n==3的子问题。观察元素排列情况,其实是有这样的规律:存在一个区间[l,r],这个区间内原始数字(指初始情况为a[i]=i)倒转后与下标的和一定是完全平方数。这样就很容易了,从较大数开始找这个可以满足条件的完全平方数,依次向前构造即可。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int N=1e5+5;
    4. int t,n;
    5. int a[N],left[N],right[N];
    6. int main(){
    7. std::ios::sync_with_stdio(false);
    8. std::cin.tie(0);
    9. std::cout.tie(0);
    10. std::cin>>t;
    11. while(t--){
    12. std::cin>>n;
    13. std::vector<int>a(n+1,0);
    14. int now=n,w=n;
    15. while(n){
    16. int t=sqrt(n);
    17. while(!(n-1<=t*t&&t*t<=2*(n-1))) t++;
    18. int u=t*t-(n-1);
    19. int len=n-u;
    20. for(int i=1;i<=len;i++){
    21. a[now]=t*t-now+1;
    22. now--;
    23. }
    24. n-=len;
    25. }
    26. for(int i=1;i<=w;i++){
    27. std::cout<" \n"[i==w];
    28. }
    29. }
    30. return 0;
    31. }

    D. Tournament Countdown

    根据序号排列,相邻两者比赛决胜负,胜者留下,败者删去,最多询问这么多次两个人的胜负情况,输出最后胜利者的编号。

    思路:看一种情况,即仅有4个人的时候,一定最后结果是0,0,1,2,0和0是第一局失败的人,2是这四个人中胜利者,保留它,这样可以以4为一组,不断重复这个操作,这样我们每次询问都可以使剩余人数成为原来的四分之一,这样计算询问次数可以这样:

    满足给出的条件。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int N=1e5+5;
    4. int t,n;
    5. int a[N],left[N],right[N];
    6. int ask(int a,int b){
    7. std::cout<<"? "<' '<
    8. int x;
    9. std::cin>>x;
    10. return x;
    11. }
    12. int main(){
    13. std::ios::sync_with_stdio(false);
    14. std::cin.tie(0);
    15. std::cout.tie(0);
    16. std::cin>>t;
    17. while(t--){
    18. std::cin>>n;
    19. int m=1<
    20. std::vector<int>a;
    21. for(int i=1;i<=1<
    22. a.push_back(i);
    23. }
    24. while(m>=4){
    25. std::vector<int>b;
    26. for(int i=0;i4){
    27. int t1=ask(a[i],a[i+2]);
    28. if(t1==0){
    29. int t2=ask(a[i+1],a[i+3]);
    30. if(t2==1) b.push_back(a[i+1]);
    31. else b.push_back(a[i+3]);
    32. }
    33. else if(t1==1){
    34. int t2=ask(a[i],a[i+3]);
    35. if(t2==1) b.push_back(a[i]);
    36. else b.push_back(a[i+3]);
    37. }
    38. else{
    39. int t2=ask(a[i+1],a[i+2]);
    40. if(t2==1) b.push_back(a[i+1]);
    41. else b.push_back(a[i+2]);
    42. }
    43. }
    44. a.swap(b);
    45. m/=4;
    46. }
    47. if(a.size()==1) std::cout<<"! "<0]<
    48. else{
    49. if(ask(a[0],a[1])==1) std::cout<<"! "<0]<
    50. else std::cout<<"! "<1]<
    51. }
    52. }
    53. return 0;
    54. }

     

  • 相关阅读:
    MQ系列14:MQ如何做到消息延时处理
    如何系统地去学python
    栈OJ(C++)
    用acme.sh给网站域名,申请免费SSL永久证书(自动续期)
    SoundTouch对音频处理(Android)
    中级java面试问题大全及答案大全
    PDF标准详解(一)——PDF文档结构
    代码审计——任意文件下载详解(二)
    向毕业妥协系列之机器学习笔记:构建ML系统(四)
    【Redis 开发】缓存穿透解决
  • 原文地址:https://blog.csdn.net/m0_62289613/article/details/126492555