如何优化打印输出两个整数中较大和较小的差异? [英] How to optimize printing out the difference between the greater and the lesser of two integers?

查看:99
本文介绍了如何优化打印输出两个整数中较大和较小的差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UVA问题编号。 10055,Hashmat the Brave Warrior ,可能是那里最容易出问题的问题。输入由一系列无符号整数≤2^ 32组成(因此要求使用64位整数......)对于每对,任务是打印出大整数和小整数之间的差异。

UVA Problem no. 10055, Hashmat the Brave Warrior, probably the easiest problem there. The input consists of a series of pairs of unsigned integers ≤ 2^32 (thus mandating the use of 64bit integers…) For each pair the task is to print out the difference between the greater and the lesser integer.

根据统计数据,最快的解决方案在0.01秒以下运行。但是,我所有解决这个问题的尝试通常都是在0.02秒内完成,可能随机偏差为±0.01秒。

According to the statistics, the fastest solutions run in below 0.01 sec. However, all my attempts to solve this typically run in 0.02 sec, with probably random deviations of ± 0.01 sec.

我试过:

#include <cstdint>
#include <iostream>
using namespace std;

int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);  

  uint_fast64_t i, j;
  while(cin >> i >> j) {
    if(i > j)
      cout << i-j << '\n';
    else
      cout << j-i << '\n';
  }
}

还有:

#include <cstdlib>
#include <cstdint>
#include <iostream>
using namespace std;

int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);  

  int_fast64_t i, j;
  while(cin >> i >> j) {
    cout << abs(i-j) << '\n';
  }
}

还有:

#include <algorithm>
#include <cstdint>
#include <iostream>
using namespace std;

int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);  

  uint_fast64_t i, j;
  while(cin >> i >> j) {
    cout << max(i,j)-min(i,j) << '\n';
  }
}

所有结果相同。

我也尝试使用 printf() / scanf()而不是 cin / cout ,仍然有相同的结果(此外,我的基准显示 cin / cout 前面有 cin.tie(nullptr)甚至可以比 printf()/ scanf()快一点 - 至少除非有一些方法可以优化 cstdio的性能我不知道)。

I also tried using printf()/scanf() instead of cin/cout, still with same results (besides, my benchmarks were showing that cin/cout preceded by cin.tie(nullptr) can be even a little faster than printf()/scanf() – at least unless there are some ways to optimize the performance of cstdio I’m not aware of).

有没有办法优化它到低于0.01秒,或者我应该假设那些已经达到这个时间的人要么是非常幸运,要么是骗子打印出对法官输入的预先计算答案?

Is there any way to optimize this down to below 0.01 sec., or should I assume that guys who’ve achieved this time are either extremely lucky or cheaters printing out a precomputed answer to the judge’s input?

程序使用 C ++ 11进行编译5.3.0 - 带有选项的GNU C ++编译器:-lm -lcrypt -O2 -std = c ++ 11 -pipe -DONLINE_JUDGE

编辑:这是我尝试结合@Sorin和@MSalters的建议:

This is my attempt to combine the advices of @Sorin and @MSalters:

#include <stdio.h>
#include <stdint.h>

unsigned long long divisors[] = {
  1000000000,
  1000000000,
  1000000000,
  1000000000,
  100000000,
  100000000,
  100000000,
  10000000,
  10000000,
  10000000,
  1000000,
  1000000,
  1000000,
  1000000,
  100000,
  100000,
  100000,
  10000,
  10000,
  10000,
  1000,
  1000,
  1000,
  1000,
  100,
  100,
  100,
  10,
  10,
  10,
  1,
  1,
  1
};


int main()
{
  unsigned long long int i, j, res;

  unsigned char inbuff[2500000]; /* To be certain there's no overflow here */
  unsigned char *in = inbuff;
  char outbuff[2500000]; /* To be certain there's no overflow here */
  char *out = outbuff;

  int c = 0;

  while(1) {
    i = j = 0;

    inbuff[fread(inbuff, 1, 2500000, stdin)] = '\0';

    /* Skip whitespace before first number and check if end of input */
    do {
      c = *(in++);
    } while(c != '\0' && !(c >= '0' && c <= '9'));

    /* If end of input, print answer and return */
    if(c == '\0') {
      *(--out) = '\0';
      puts(outbuff);
      return 0;
    }

    /* Read first integer */
    do {
      i = 10 * i + (c - '0');
      c = *(in++);
    } while(c >= '0' && c <= '9');

    /* Skip whitespace between first and second integer */
    do {
      c = *(in++);
    } while(!(c >= '0' && c <= '9'));

    /* Read second integer */
    do {
      j = 10 * j + (c - '0');
      c = *(in++);
    } while(c >= '0' && c <= '9');

    if(i > j)
      res = i-j;
    else
      res = j-i;



    /* Buffer answer */
    if(res == 0) {
      *(out++) = '0';
    } else {
      unsigned long long divisor = divisors[__builtin_clzll(res)-31];
      /* Skip trailing 0 */
      if(res < divisor) {
        divisor /= 10;
      }
      /* Buffer digits */
      while(divisor != 0) {
        unsigned long long digit = res / divisor;
        *(out++) = digit + '0';
        res -= divisor * digit;
        divisor /= 10;
      }
    }
    *(out++) = '\n';
  }
}   

仍为0.02秒。

推荐答案

我会尝试消除IO操作。
读取一个数据块(尽可能大)。
计算输出,将它们写入另一个字符串,然后将该字符串写出来。

I would try to eliminate IO operations. Read one block of data (as big as you can). Compute the outputs, write them to another string then write that string out.

你可以使用sscanf或stringstream来读取/写入你的内存块。

You sscanf or stringstream equivalents to read/write from your memory blocks.

IO通常需要通过内核,所以你可能会稍微松开CPU。还有一些成本(时间)与之相关。它虽小,但你试图在不到10毫秒的时间内运行。

IO usually needs to go through the kernel so there's a small chance that you would loose the CPU for a bit. There's also some cost(time) associated with it. It's small but you are trying to run in less than 10ms.

这篇关于如何优化打印输出两个整数中较大和较小的差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆