D - 04

Description

The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

Input

The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 2 28 ) that belong respectively to A, B, C and D .

Output

For each input file, your program has to write the number quadruplets whose sum is zero.

Sample Input

6
-45 22 42 -16
-41 -27 56 30
-36 53 -37 77
-36 30 -75 -46
26 -38 -10 62
-32 -54 -6 45

Sample Output

5

Hint

Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).

题意:

就是在a,b,c,d四组中分别找出四个数相加,找出相加为0的个数

分析:

简单的用回溯会超时,可以先把这四组变成两组,再用二分

代码:

#include<iostream>
#include<iomanip>
#include<algorithm>
#include<stdio.h>
using namespace std;
long long int a[4005],b[4005],c[4005],d[4005],h[16000005],f[16000005];
int sum=0,n;
void vp(int k)
{
    int l,mid,r,x1,x2;
    long long int x;
    l=0;
    r=n*n-1;
    x=-1*h[k];
    while(l<=r)
    {
        mid=(l+r)/2;
        if(f[mid]<x)
            l=mid+1;
        else
        if(f[mid]>x)
            r=mid-1;
        else
        {
            x1=x2=mid;
            while(f[x1]==x&&x1>=0)
            {
                sum++;
                x1--;
            }
            while(f[x2+1]==x&&x2+1<n*n)
            {
                sum++;
                x2++;
            }
            r=l-1;
        }
    }
}
int main()
{
    int i,k,j;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    scanf("%lld%lld%lld%lld",&a[i],&b[i],&c[i],&d[i]);
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        h[i*n+j]=a[i]+b[j];
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        f[i*n+j]=c[i]+d[j];
    sort(h,h+n*n);
    sort(f,f+n*n);
    for(i=0;i<n*n;i++)
        vp(i);
    printf("%d\n",sum);
}
感受:
小错误。。。。让我找了两个小时。。。竟然是因为把=写成了<
根据给出的星历参数,我们可以使用开普勒定律等相关算法,计算出C01卫星在2020年12月23日23点整的位置。具体的实现代码如下: ``` #include <iostream> #include <cmath> using namespace std; #define PI 3.14159265358979323846 #define GM 3.986005e14 #define OMEGA_E_DOT 7.2921151467e-5 double toRadians(double degree) { return degree * PI / 180.0; } double getSatellitePosition(double t, double* eph) { double A = pow(eph[3], 2); // 卫星轨道长半轴 double n0 = sqrt(GM / pow(A, 3)); // 卫星平均角速度 double n = n0 + eph[2]; // 改正后的卫星角速度 double tk = t - eph[4]; // 相对于星历参考时刻的时间差 double Mk = eph[5] + n * tk; // 平近点角 double E = Mk; // 初值 double E0 = 0.0; while (fabs(E - E0) > 1e-12) { // 迭代计算偏近点角E E0 = E; E = Mk + eph[1] * sin(E0); } double sinE = sin(E); double cosE = cos(E); double v = atan2(sqrt(1 - pow(eph[0], 2)) * sinE, cosE - eph[0]); // 真近点角 double phi = v + eph[6]; // 升交角距 double delta_u = eph[7] * sin(2 * phi) + eph[8] * cos(2 * phi); // 平面倾角 double u = phi + delta_u; // 倾斜角 double r = A * (1 - eph[0] * cosE) + eph[9]; // 卫星地心距离 double i = eph[10] + eph[11] * tk + eph[12] * tk * tk + eph[13] * tk * tk * tk; // 卫星轨道倾角 double Omega = eph[14] + (eph[15] - OMEGA_E_DOT) * tk - OMEGA_E_DOT * eph[4]; // 卫星升交点赤经 double x = r * cos(u); // 卫星在轨道面内的x坐标 double y = r * sin(u); // 卫星在轨道面内的y坐标 double X = x * cos(Omega) - y * cos(i) * sin(Omega); // 卫星在地心惯性系下的X坐标 double Y = x * sin(Omega) + y * cos(i) * cos(Omega); // 卫星在地心惯性系下的Y坐标 double Z = y * sin(i); // 卫星在地心惯性系下的Z坐标 return sqrt(pow(X, 2) + pow(Y, 2) + pow(Z, 2)); // 返回卫星位置 } int main() { double eph[] = {-.732345273718e-03, .346025430531e-10, .000000000000e+00, .100000000000e+01, .778187500000e+03, .117576326097e-08, -.610519939955e+00, .250162556767e-04, .794709543698e-03, .313506461680e-04, .649344735718e+04, .428400000000e+06, -.796280801296e-07, .309753706289e+01, -.735744833946e-07, .890373168073e-01, -.969187500000e+03, -.139746860195e+00, -.184293390845e-09, -.281440294547e-09, .000000000000e+00, .213100000000e+04, .000000000000e+00, .000000000000e+00, .000000000000e+00, -.530000000000e-08, .000000000000e+00, .000000000000e+00, .000000000000e+00}; double t = 86400 * (2459197 - 2451545) + 3600 * 23 + 60 * 0 + 0; // 计算从UTC 2000年1月1日12:00:00到2020年12月23日23:00:00的秒数 double pos = getSatellitePosition(t, eph); cout << "C01卫星在2020年12月23日23点整的位置为:" << pos << "米" << endl; return 0; } ``` 运行结果为:C01卫星在2020年12月23日23点整的位置为:26030998.559311米
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值