zoukankan      html  css  js  c++  java
  • poj 2785 让和为0 暴力&二分

    题目链接:http://poj.org/problem?id=2785

    大意是输入一个n行四列的矩阵,每一列取一个数,就是四个数,求有多少种着四个数相加和为0的情况

    首先脑海里想到的第一思维必然是一个个枚举,用四个for循环,那时间复杂度变成了On4,n的最大值是4000.

    肯定会超时。那么,为了简化时间,首先我们可以开两个至少4000*4000的数组分别把第一列与第二列的和的情况

    ,第三列与第四列的和的情况存起来。这样就只用考虑两个数组的情况。

    然后把两个数组排序,一个数组从头部开始同时另一个数组从尾部开始讨论和为0的情况(利用了递增性质和递减性质)

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 int a[4001],b[4001],c[4001],d[4001];
     5 int ab[4000*4000+1],cd[4000*4000+1];
     6 int main()
     7 {
     8     int n,i,j,k,num,sum,x;
     9     while (~scanf("%d",&n))
    10     {
    11         for (i=0;i<n;i++)
    12             scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]);
    13         k=0;
    14         for (i=0;i<n;i++){
    15             for (j=0;j<n;j++)
    16                ab[k++]=a[i]+b[j];
    17         }
    18         k=0;
    19         for (i=0;i<n;i++){
    20             for (j=0;j<n;j++)
    21                cd[k++]=c[i]+d[j];
    22         }
    23         sort(ab,ab+n*n);
    24         sort(cd,cd+n*n);
    25         x=n*n-1;sum=0;
    26         for (i=0;i<n*n;i++)
    27         {
    28             while (x>=0&&ab[i]+cd[x]>0)
    29                 x--;
    30             if (x<0)
    31                 break;
    32             num=x;
    33             while (ab[i]+cd[num]==0&&num>=0)
    34             {
    35                 sum++;
    36                 num--;
    37             }
    38         }
    39         printf("%d
    ",sum);
    40     }
    41     return 0;
    42 }

    二分也很简单,找到相等个数就行

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 int a[4001],b[4001],c[4001],d[4001];
     6 int ab[4000*4000+1],cd[4000*4000+1];
     7 int k2;
     8 int check(int x)
     9 {
    10     int left=1,right=k2-1,mid;
    11     while (left<=right)
    12     {
    13         mid=(left+right)/2;
    14         if (x==cd[mid])
    15         {
    16             int w=0,e=mid;
    17             while (x==cd[e]&&e<k2)
    18                 e++,w++;
    19             e=mid-1;
    20             while (x==cd[e]&&e>0)
    21                 e--,w++;
    22             return w;
    23         }
    24         else if (x<cd[mid])
    25             right=mid-1;
    26         else
    27             left=mid+1;
    28     }
    29     return 0;
    30 }
    31 int main()
    32 {
    33     int t,i,j,q;
    34     while (~scanf("%d",&t))
    35     {
    36         for (i=1;i<=t;i++)
    37             scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]);
    38         memset(ab,0,sizeof(ab));
    39         memset(cd,0,sizeof(cd));
    40         int k1=1,sum=0;
    41         k2=1;
    42         for (i=1;i<=t;i++)
    43         {
    44             for (j=1;j<=t;j++)
    45             {
    46                 ab[k1++]=a[i]+b[j];
    47                 cd[k2++]=-(c[i]+d[j]);
    48             }
    49         }
    50         sort(cd+1,cd+k2);
    51         for (i=1;i<k1;i++)
    52             sum+=check(ab[i]);
    53         printf("%d
    ",sum);
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    大二暑假学习第一周
    PyQt5+pycharm 中对生成的.py文件无法运行的问题
    尚筹网19总结
    尚筹网19项目部署
    MAC远程连接Linux
    尚筹网17订单、支付
    尚筹网16确认回报、订单
    支付宝沙箱环境
    内网穿透
    支付宝开发平台使用
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/4663553.html
Copyright © 2011-2022 走看看