【问题标题】:time limit error exceeding due to modulo(10,9)+7 maybe?可能由于模(10,9)+7 导致超出时间限制错误?
【发布时间】:2019-12-17 20:15:46
【问题描述】:

我们的 X 轴上有 N 个士兵。士兵所在的位置也有一些炸弹。 战争临近,每个士兵都想与其他士兵交流。 如果i-th士兵有b个炸弹并且位于位置X,那么与任何其他在位置Y有c个炸弹的士兵j通信的成本被定义为|X-Y|*max(b,c)。 如果每个士兵都想与其他士兵交流,求交流成本的总和。 注意:- 您必须在总成本中只考虑一次 pair(i,j)。

输入格式:

第一行包含测试用例的数量 T。每个测试用例包含三行。第一行表示士兵人数(N)。第二行表示 N 个士兵的坐标( X[i] )。第三行包含每个士兵位置的炸弹数量 (B[i])。 x 坐标在输入中不必按升序排列。 约束

1 <= T <= 20 1 <= N <= 200000 1 <= X[i] <= 1000000000 1 <= B[i] <= 10000

输出格式:

总成本模 10^9+7。 样本输入

1
3  
1 3 6  
10 20 30  

样本输出

280

解释

有 3 对 (1,2) -> 成本 = abs(3-1) * 20 = 40 (1,3) -> 成本 = abs(1-6) * 30 = 150 (2,3) -> 成本 = abs(3-6) * 30 = 90 总和 = 40 + 150 + 90 = 280

我正在处理模数 (10^9+7) 和一切使用蛮力但得到低于其的 tle 代码也适用于上述情况但它是那些烦人的 tle/类型转换类型的问题之一。任何回应都非常感谢-

import java.util.*;
public class Main {
public static void main(String args[]) {
    Scanner sc= new Scanner(System.in);
    int T=sc.nextInt();

    for(int ctr=0;ctr<T;ctr++)
    {
        int N=sc.nextInt();
        long [] x= new long[N];
        long [] b= new long[N];
        for(int i=0;i<N;i++)
        {
            x[i]=sc.nextLong();

        }
        for(int i=0;i<N;i++)
        {
            b[i]=sc.nextInt();

        }
        int cost=0;
        double v;
        for(int i=0;i<N-1;i++)
        {
            for(int j=i+1;j<N;j++)
            {
                v= x[i]%(Math.pow(10,9)+7)-x[j]%(Math.pow(10,9)+7);
                v=Math.abs(v)%(Math.pow(10,9)+7);
                cost+= v*Math.max(b[i],b[j]);
            }
        }
        System.out.println(cost);

    }
}   }

【问题讨论】:

  • 我建议你多强调一下问题是什么,因为它不是很清楚,而且在冗长的描述中有点迷失
  • 10^9+7 是一个常数!这只是 1000000007L !不要为每个循环迭代计算 3 次。
  • 格式化文本
  • 一个使用 SO 解决竞争性编程问题的明显案例 :)
  • 无论你做什么,有 200k 士兵,就有 2e10 对,所以除非你能将循环减少到几条指令,否则暴力破解是没有意义的。我想,你需要一个更智能的算法。

标签: java optimization


【解决方案1】:

正如@Erwin 所建议的,不要在for 循环的每次迭代中使用Math.pow() 来计算(10^9)+7 三次。相反,将其置于循环之外(也许将其定义为常量),然后执行您的操作。

此外,您在运算中对 (10^9)+7 常量进行两次模运算。你确定这是预期的操作吗?您在v 的第一次计算中执行此操作,然后在v 的第二次计算中再次执行此操作。如果您只需要它来支付最终费用,您可以从第一步中删除它。

这是我的代码,你可以试试:

import java.util.*;
public class Main {
public static void main(String args[]) {
    double moduloNumber = (Math.pow(10,9)+7);
    Scanner sc= new Scanner(System.in);
    System.out.print("Enter the Number of Test Cases (1 <= T <= 20): ");
    int T=sc.nextInt();

    for(int ctr=0;ctr<T;ctr++)
    {
        System.out.print("\nEnter the Number of Soldiers (1 <= N <= 200000): ");
        int N=sc.nextInt();
        long [] x= new long[N];
        long [] b= new long[N];
        for(int i=0;i<N;i++)
        {
            System.out.print("Enter the Position of Soldier " + (i+1) + " (1 <= X[i] <= 1000000000): ");
            x[i]=sc.nextLong();

        }
        for(int i=0;i<N;i++)
        {
            System.out.print("Enter the Number of Bombs with Soldier " + (i+1) + " (1 <= B[i] <= 10000): ");
            b[i]=sc.nextInt();

        }
        int cost=0;
        double v;
        for(int i=0;i<N-1;i++)
        {
            for(int j=i+1;j<N;j++)
            {
                v=(x[i]-x[j]);
                v=Math.abs(v)%(moduloNumber);
                cost+= v*Math.max(b[i],b[j]);
            }
        }
        System.out.println(cost);

    }
}
}

我只是添加了一些打印语句并将模常数移到循环之外以降低计算成本。您可以检查这是否解决了目的。

问候,

AJ

【讨论】:

  • 你能给我给出错误的样本值吗?我会看看我能做什么。
  • 一般来说,在竞技编程中,10^9+7 是一个边缘情况,如果处理不当,你会得到 TLE 错误。您需要降低计算成本才能避免出现错误。您将 Array b 定义为 long 但随后将整数作为输入。如果可能,您可以将数组 x 和 b 都定义为整数并且只取整数值。此外,尝试将您的成本变量更改为双精度或将所有内容转换为整数,因为整数的百分比将是整数。让我知道这是否有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 2017-09-23
相关资源
最近更新 更多