There are n robots, each with a position (x, y). The first line gives n, and the next n lines give the positions "x y" of robots 1 to n. Then comes the number of commands q, followed by q lines with one command each. Robots are numbered from 1.
- move i dx dy: robot i moves by dx in x and dy in y.
- copy i j: set robot i's position equal to robot j's current position. After that the two robots move independently of each other.
- swap i j: exchange the positions of robots i and j.
i and j may be equal. After carrying out the commands in order, print the positions of robots 1 to n, one per line, as "x y". Try modeling a position as a struct with two members x and y, and doing copy with a single struct assignment.
Input
1 ≤ n ≤ 1,000, 1 ≤ q ≤ 10,000, initial coordinates and dx, dy are integers from -1,000 to 1,000
When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).
$ Ready
Open this on a computer to write and run code. On mobile you can read the problem and the solutions.
In other languagesShow solutions by language · 3 languages
This problem accepts only C, C++ and C#. Those three let you define a value-type struct whose whole data is copied on assignment. Objects in Python, JavaScript, TypeScript and Java, and Craykon's Dict(), are references that share the same thing when assigned, so this problem's copy would need an explicit copy there. In C and C++, r[i] = r[j] copies every member, and the two robots then move separately. C# copies the same way for struct Point, but with class Point the same assignment copies only the reference, so moving one afterwards moves both slots. Three traps: (1) in C, taking it by value as void move(Point p, int dx, int dy) moves only the copy and the robot in the array stays put; take Point *p, call move(&r[i], dx, dy), and write p->x += dx inside (in C++ a member function or Point&). (2) In C#, turning struct into class merges the two robots after copy. (3) In C#, r[i].Move(dx, dy) on a List<Point> compiles with no error, but it moves only the copy the indexer returned and throws it away. An element of an array Point[] is a variable, so r[i].Move() changes the element itself. With a List, take it out, change it and put it back (var p = r[i]; p.Move(dx, dy); r[i] = p;).
C#Main.cs · 41 lines
using System;using System.IO;using System.Text;struct Point // 값 타입: 대입하면 데이터가 복사된다{ public int X, Y; public void Move(int dx, int dy) { X += dx; Y += dy; }}class Program{ static void Main() { string[] t = Console.In.ReadToEnd().Split((char[])null, StringSplitOptions.RemoveEmptyEntries); int pos = 0; int n = int.Parse(t[pos++]); var r = new Point[n]; // 배열 칸은 변수라서 r[i].Move()가 칸 자체를 바꾼다 for (int i = 0; i < n; i++) r[i] = new Point { X = int.Parse(t[pos++]), Y = int.Parse(t[pos++]) }; int q = int.Parse(t[pos++]); for (int k = 0; k < q; k++) { string cmd = t[pos++]; int i = int.Parse(t[pos++]) - 1; if (cmd == "move") { int dx = int.Parse(t[pos++]), dy = int.Parse(t[pos++]); r[i].Move(dx, dy); } else { int j = int.Parse(t[pos++]) - 1; if (cmd == "copy") r[i] = r[j]; // 복사본이 들어가서 이후 따로 움직인다 else (r[i], r[j]) = (r[j], r[i]); } } var sb = new StringBuilder(); foreach (var p in r) sb.Append(p.X).Append(' ').Append(p.Y).Append('\n'); Console.Write(sb); }}
C++main.cpp · 38 lines
#include <iostream>#include <string>#include <utility>#include <vector>struct Point { int x, y; void move(int dx, int dy) { // 멤버 함수는 자기 자신(원본)을 바꾼다 x += dx; y += dy; }};int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n, q; std::cin >> n; std::vector<Point> r(n); for (auto& p : r) std::cin >> p.x >> p.y; std::cin >> q; std::string cmd; for (int k = 0; k < q; k++) { int i, j, dx, dy; std::cin >> cmd; if (cmd == "move") { std::cin >> i >> dx >> dy; r[i - 1].move(dx, dy); // vector의 operator[]는 참조를 돌려줘서 원본이 바뀐다 } else if (cmd == "copy") { std::cin >> i >> j; r[i - 1] = r[j - 1]; // 값 복사 } else { std::cin >> i >> j; std::swap(r[i - 1], r[j - 1]); } } for (const auto& p : r) std::cout << p.x << " " << p.y << "\n";}
Cmain.c · 39 lines
#include <stdio.h>#include <string.h>typedef struct { int x, y;} Point;/* 원본을 움직이려면 포인터로 받는다 */void move(Point *p, int dx, int dy) { p->x += dx; p->y += dy;}int main(void) { static Point r[1000]; int n, q; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d %d", &r[i].x, &r[i].y); scanf("%d", &q); char cmd[8]; for (int k = 0; k < q; k++) { int i, j, dx, dy; scanf("%7s", cmd); if (strcmp(cmd, "move") == 0) { scanf("%d %d %d", &i, &dx, &dy); move(&r[i - 1], dx, dy); } else if (strcmp(cmd, "copy") == 0) { scanf("%d %d", &i, &j); r[i - 1] = r[j - 1]; /* 구조체 대입은 멤버를 통째로 복사: 이후 둘은 따로 움직인다 */ } else { scanf("%d %d", &i, &j); Point t = r[i - 1]; r[i - 1] = r[j - 1]; r[j - 1] = t; } } for (int i = 0; i < n; i++) printf("%d %d\n", r[i].x, r[i].y); return 0;}