#P3032. 计算面积(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 137
            Accepted: 56
            Difficulty: 5
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>模拟          
 
计算面积(100分)
思路:模拟
我们可以一边扫描,一边计算每一条指令的增量面积(因为对于X轴来说,一直是往一个方向移动)
设执行到前i−1条指令之后,当前点的纵坐标为yi,那么在执行第i条指令时,对应的增量面积为(x−last)∗abs(yi),x和last分别为执行完第i条指令前后的横坐标的值。
按照上述步骤一边计算,一边更新各个坐标的值即可。
代码
JavaScript
const readline = require('readline');
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
rl.question('', (line1) => {
  const [n, e] = line1.split(' ').map(x => parseInt(x));
  let lastX = 0;   // 记录上一个位置的横坐标
  let y = 0;       // 记录起始点的纵坐标
  let area = 0;    // 记录面积
  let count = n;
  rl.on('line', (line) => {
    const [x, d] = line.split(' ').map(x => parseInt(x));
    area += (x - lastX) * Math.abs(y);   // 计算执行第i个指令后的增量面积
    y += d;   // 更新纵坐标
    lastX = x; // 更新上一个位置的横坐标
    if (--count === 0) {
      area += (e - lastX) * Math.abs(y);   // 计算终点的增量面积
      console.log(area);
      rl.close();
    }
  });
});
Java代码
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int e = scanner.nextInt();
        long lastX = 0;   //记录上一个位置的横坐标
        long y = 0;       //记录起始点的纵坐标
        long area = 0;    //记录面积
        for (int i = 0; i < n; i++) {
            long x = scanner.nextLong();
            long d = scanner.nextLong();
            area += (x - lastX) * Math.abs(y);   //计算执行第i个指令后的增量面积
            y += d;   //更新纵坐标
            lastX = x; //更新上一个位置的横坐标
        }
        area += (e - lastX) * Math.abs(y);   //计算终点的增量面积
        System.out.println(area);
        scanner.close();
    }
}
Python代码
n, e = map(int, input().split())
last_x = 0   # 记录上一个位置的横坐标
y = 0      # 记录起始点的纵坐标
area = 0    # 记录面积
for i in range(n):
    x, d = map(int, input().split())
    area += (x - last_x) * abs(y)   # 计算执行第i个指令后的增量面积
    y += d   # 更新纵坐标
    last_x = x   # 更新上一个位置的横坐标
area += (e - last_x) * abs(y)   # 计算终点的增量面积
print(area)
C++代码
#include <iostream>
#include <cmath>
using namespace std;
int main() {
    int n, e;
    cin >> n >> e;
    long long last_x = 0;   // 记录上一个位置的横坐标
    long long y = 0;      // 记录起始点的纵坐标
    long long area = 0;    // 记录面积
    for (int i = 0; i < n; i++) {
        long long x, d;
        cin >> x >> d;
        area += (x - last_x) * abs(y);   //计算执行第i个指令后的增量面积
        y += d;   //更新纵坐标
        last_x = x; //更新上一个位置的横坐标
    }
    area += (e - last_x) * abs(y);   //计算终点的增量面积
    cout << area << endl;
    return 0;
}
        题目描述
绘图机器的绘图笔初始位置在原点 (0,0),机器启动后其绘图笔按下面规则绘制直线:
1)尝试沿着横向坐标轴正向绘制直线,直到给定的终点值 E
2)期间可通过指令在纵坐标轴方向进行偏移,并同时绘制直线,偏移后按规则 1 绘制直线,指令的格式为 X offsetY,表示在横坐标 X 沿纵坐标方向偏移,offsetY 为正数表示正向偏移,为负数表示负向偏移。给定了横坐标终点值 E 、以及若干条绘制指令,请计算绘制的直线和横坐标轴、以及 X=E 的直线组成图形的面积
输入描述
首行为两个整数 N E,表示有 N 条指令,机器运行的横坐标终点值 E 接下来 N 行,每行两个整数表示一条绘制指令 XoffsetY,用例保证横坐标 X 以递增排序方式出现,且不会出现相同横坐标X 。取值范围: 0<N≤10000 ,0≤X≤E≤20000.−10000≤offsetY≤10000.
样例1
输入
4 10
1 1
2 1
3 1
4 -2
输出
12
说明:通过操作及其最后绘制出如下图形(蓝色为绘制笔绘制的直线)

样例2
输入
2 4
0 1
2 -2
输出
4
说明:通过操作机器最后绘制了如下图形
