The things that talk about algorithmic problems (1)

Source: Internet
Author: User
Tags array sort printf sort cmath

1. Cemetery Sculpture (Graveyard, Neerc 2006, LA 3708)
n sculptures are distributed equidistant on a circle with a circumference of 10000. Now there is a new m sculpture (position can be placed at will), I hope all n+m sculpture on the circumference evenly distributed. This will require some of the original sculptures to be moved. The total distance required to move the n sculptures is as small as possible.
"Input Format"
The input contains several sets of data. Each group of data is only one row, containing two integers n and m (2≤n≤1 000,1≤m≤1 000), which is the original number of sculptures and the number of newly added sculptures. The input end flag is the file Terminator (EOF).
"Output Format"
Enter only one row, which is the minimum total distance, accurate to 10-4.
"Sample Input"

2 1
2 3
3 1
10 10

"Sample Output"

1666.6667
1000.0
1666.6667
0.0

"Sample Interpretation"
The first 3 examples are shown in the figure. White hollow dots indicate equidistant points, and black segments indicate existing sculptures.

Analysis
Please take a closer look at the sample. 3 examples have a common feature: there is a sculpture that does not move. If the feature is established in all cases, the final position of all sculptures (called the "target Point") is actually determined. For the sake of simplicity, we take the motionless sculpture as the origin of the coordinates, and the other sculptures are labeled in the counterclockwise order to the distance from the origin, as shown in the figure.


Note that the distance here is not the real distance, but the distance is scaled down. Next, we move each sculpture to its nearest position. If no two statues are moved to the same position, then such movement must be optimal. The code is as follows.

#include <cstdio>
#include <cmath>
using namespace std;

int main () {
  int n, m;
  while (scanf ("%d%d", &n, &m) = = 2) {
    double ans = 0.0;
    for (int i = 1; i < n; i++) {
      Double pos = (double) i/n * (n+m);       Calculate coordinates for each sculpture that needs to be moved
      ans + = fabs (Pos-floor (pos+0.5))/(n+m);    Add move Distance
    }
    printf ("%.4lf\n", ans*10000);               Equal proportional expansion of coordinates
  }
  return 0;
}

Note In the code, the object where the sculpture coordinates to POS is moved to IS floor (pos+0.5), which is the result of the POS rounding. This is the benefit of narrowing the coordinates.
This code magically passes the test, but in fact the algorithm has two small "holes": first of all, we do not know whether there must be a sculpture does not move, and secondly, we do not know whether there will be two of the sculptures would move to the same position. If you're not interested in proof, or have thought of proving, or can't wait to read more interesting questions, skip to the next example. Otherwise, please continue reading.
The first "bug" Patch needs to prove our conjecture. Proof of ideas In Example 3 we have shown that the specific details left to the reader to think.
The second "vulnerability" has two methods of patching. The first method is relatively easy to implement: Because n is specified in the topic,
M≤1 000, we only need to add a function in the program-to record each sculpture moved to the target location, you can use the program to determine whether there will be "more people pit less" situation. This program is written to the reader, here can clearly tell you: this situation does not appear. In this way, even if it is impossible to prove theoretically, we can ensure that our algorithm is strict within the scope of the topic.
The second method is to prove it directly. In our program, when the coordinate system is scaled, the sculpture with x coordinates is moved to the position after X is rounded. If a sculpture with two coordinates x and Y is moved to the same position, the result of X and Y rounding is the same, in other words, X and Y are "very close". As to how close it is. The biggest difference is similar to x=0.5, y=1.499 999 .... Even in this case, Y-x is still less than 1 (although very close to 1), but this is not possible, because after the new sculpture, the distance of the adjacent sculpture is equal to 1, before the number of sculptures less, the distance should be greater.
Example 5 ant (Piotr ' s Ants, UVa 10881)
An L-centimetre-long stick has n ants on it, and each ant either climbs to the left or climbs to the right, at a speed of 1 centimeters per second. When two ants collide, they turn around at the same time (turn-around is negligible). Give the initial position and orientation of each ant, and calculate the position of each ant after t seconds.
"Input Format"
The number of first-action data groups entered. The first behavior of each group of data is 3 positive integer l, T, N (0≤n≤10 000); The following n rows each describe the initial position of an ant, where the integer x is the distance (in centimeters) of the ant from the left end of the stick, the letter representing the initial orientation (l means toward the left and R for the right).
"Output Format"
For each set of data, output n rows, output the position and orientation of each ant in the input order (turning indicates a collision). An ant that has fallen off a stick before the first T (not counting the edge of the stick) outputs fell off.
"Sample Input"

2
10 1 4
0 3
4 3
3 L
Ten R
10 2 3
5 3
5 L
8 R

"Sample Output"

Case #1:
2 Turning
3 7
2 Turning
Fell off

Case #2:
3 L
3 7
Ten R

Analysis
Suppose you look at the movements of these ants in the distance and see what happens. A group of small black dots are moving. Because the black dot is too small, when the ant is turned around because of a collision, it does not make any difference to the two dots "to wear", in other words, if the ant is regarded as an indistinguishable point, it is only necessary to calculate the position of each ant at the T moment independently. For example, there are 3 ants, ant 1= (1, R), Ant 2= (3, L), Ant 3= (4, L), two seconds later, 3 ants are (3,r), (1,l) and (2,l) respectively.
Note that although the "turn-around" is equivalent to "over-worn" on the whole, it is not the case for every ant. The initial state of Ant 1 is (1,r), so there must be an ant in the state (3,r) after two seconds, but the ant is not necessarily an ant 1. In other words, we need to figure out "who is who" in the target state.
Perhaps the reader has discovered the mystery: the relative order of all ants remains constant, so that all target locations are sorted from small to large, and each position from left to right corresponds to each ant from left to right in its initial state. Because the ants do not necessarily enter from left to right in the original question, they also need preprocessing to calculate the ordinal number of the ant in the input order[i]. The complete code is as follows.

#include <cstdio> #include <algorithm> using namespace std;

const int MAXN = 10000 + 5;   struct ANT {int id;    Input order int p;    position int D; Towards. -1: Left; 0: Turn in;
  1: Right bool operator < (const ant& a) const {return P < A.P;

}} BEFORE[MAXN], AFTER[MAXN];

const char DIRNAME[][10] = {"L", "Turning", "R"}; int ORDER[MAXN];
  The input of the first ant is the end state in the left number of order[i] only ant int main () {int K;
  scanf ("%d", &k);
    for (int kase = 1; kase <= K; kase++) {int L, T, N;
    printf ("Case #%d:\n", Kase);
    scanf ("%d%d%d", &l, &t, &n);
      for (int i = 0; i < n; i++) {int p, D;
      char c;
      scanf ("%d%c", &p, &c);
      D = (c = = ' L '? -1:1);
      Before[i] = (Ant) {i, p, d};    After[i] = (Ant) {0, p+t*d, d};
    The ID here is unknown}//Calculate order array sort (before, before+n);

    for (int i = 0; i < n; i++) order[before[i].id] = i;    
    Calculates the end-state sort (after, after+n); for (int i = 0; i < n-1; i++)//Modify TouchThe direction of the hit ant if (after[i].p = = after[i+1].p) after[i].d = AFTER[I+1].D = 0; 
      Output result for (int i = 0; i < n; i++) {int a = Order[i];
      if (AFTER[A].P < 0 | | after[a].p > L) printf ("Fell off\n");
    else printf ("%d%s\n", AFTER[A].P, dirname[after[a].d+1]);
  } printf ("\ n");
} return 0; }

Example 6 cube imaging (image is everything, World Finals 2004, LA 2995)
There is a nxnxn cube where some of the unit cubes are missing (the rest is not necessarily connected). Each unit cube weighs 1 grams and is coated with a single color (i.e. 6 faces of the same color). Give the front, left, back, right, top, and bottom 6 views, your task is to determine the maximum weight of the object remaining.
"Input Format"
The input contains multiple sets of data. The first behavior of each group of data is an integer n (1≤n≤10); The following n rows each row from left to right in the front, left, back, right, top, bottom 6 views, each of which occupies n columns, and the middle of the adjacent view is separated by a space. The bottom bounds of the top view correspond to the upper bounds of the front views, and the upper bounds of the bottom view correspond to the bottom bounds of the front view. In the view, uppercase letters represent colors (different letters indicate different colors), and periods (.) indicate that the position can be seen through (that is, there are no cubes). The input end flag is n=0.
"Output Format"
For each set of data, the output line is the maximum weight of the object (in grams).
"Sample Input"

3
. R. Yyr. Y. Ryy. Y.. R.
GRB ygr BYG Rby gyb GRB
. R. Yrr. Y. Rry. R.. Y.
2
ZZ ZZ ZZ ZZ ZZ-ZZ
ZZ ZZ ZZ ZZ ZZ-ZZ
0

"Sample Output"

Maximum weight:11 Gram (s)
Maximum weight:8 Gram (s)

Analysis
The problem seems a little tricky, but it can still be found. For example, all unit cubes corresponding to the "see through" position must not exist. For example, if the upper-right corner of the front view has a different color B from the top-right corner, then the corresponding lattice must not exist. As shown in the figure.

After we delete this cube, we may have a new discovery: the colors of C and D are different. In this way, we can delete a new cube and expose the new surface. When the deletion cannot continue, the remaining cube is the object with the greatest weight.
Some readers may have doubts about the algorithm. The explanation is as follows: First it is not difficult to prove that the first deletion is necessary (that is, the deleted cube cannot exist in any feasible solution), because as long as the cube is not deleted, the corresponding two views of the "contradiction" will always exist; Next, we use the mathematical induction method, assuming that the first k delete is necessary, then the first Is it necessary to delete 1 times? By the reasoning just now, we cannot eliminate the contradiction by continuing to delete the cube, and by the inductive hypothesis, the deleted cube cannot be restored, so the contradiction cannot be eliminated. The complete code is given below the
.

#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std;
#define REP (I,n) for (int i = 0; I < (n); i++) const int MAXN = 10;
int n;
Char POS[MAXN][MAXN][MAXN];

Char VIEW[6][MAXN][MAXN];
  Char Read_char () {char ch; for (;;)
    {ch = getchar ();
  if (ch >= ' A ' && ch <= ' Z ') | | ch = = '. ') return ch;  
  }} void get (int k, int i, int j, int len, int &x, int &y, int &z) {if (k = = 0) {x = len; y = j; z = i;}
  if (k = = 1) {x = n-1-J; y = len; z = i;}
  if (k = = 2) {x = n-1-len; y = n-1-J; z = i;}
  if (k = = 3) {x = j; y = n-1-len; z = i;}
  if (k = = 4) {x = n-1-i; y = j; z = Len;}

if (k = = 5) {x = i; y = j; z = n-1-len;}}
    int main () {while (scanf ("%d", &n) = = 1 && N) {rep (i,n) Rep (k,6) Rep (j,n) view[k][i][j] = Read_char ();

    Rep (I,n) Rep (J,n) Rep (k,n) pos[i][j][k] = ' # ';
    Rep (k,6) Rep (I,n) Rep (j,n) if (view[k][i][j] = = '. ')  REP (p,n) {int x, y, Z;
        Get (k, I, J, p, X, Y, z);
      Pos[x][y][z] = '. '; } for (;;)
      {bool done = true; Rep (k,6) Rep (I,n) Rep (j,n) if (view[k][i][j]! = '. ')
          {REP (p,n) {int x, y, Z;
          Get (k, I, J, p, X, Y, z);
          if (pos[x][y][z] = = '. ') continue;
            if (pos[x][y][z] = = ' # ') {pos[x][y][z] = view[k][i][j];
          Break
          } if (pos[x][y][z] = = View[k][i][j]) break;
          Pos[x][y][z] = '. ';
        Done = false;
    }} if (done) break;
    } int ans = 0;

    Rep (I,n) Rep (J,n) Rep (k,n) if (pos[i][j][k]! = '. ') ans + +;
  printf ("Maximum Weight:%d gram (s) \ n", ans);
} return 0; }

The

program uses a Get function to represent the coordinates (x, y, z) of the unit cube in the original cube in the K-row J column, the depth of Len, and the macro rep refiner. Although using macros to shorten the code in many cases can reduce the readability of the program, the subject does not (if there is a for loop everywhere, it is easy to stun).

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.