The eighth annual school competition of Zhengzhou University

Source: Internet
Author: User
Tags abs greatest common divisor printf
Problem A:squee_spoon and his cube II is the simulation of a second-order Rubik's Cube, Rubik's Cube has a character is a specific sequence, and then will be in a certain number of times back to the original state, but the greater the number of orders, the more the number of times, the second number is very small. For this problem, a two-dimensional array is used to represent a polygon, and each operation changes the array as it goes, until it returns to its original state, and we assume that the initial state is a restored second-order Rubik's Cube. What I'm writing here is to use a structure to represent a face, and the structure of number 0-5 indicates the upper and lower sides respectively. For the front and back of the four face, you face these four faces, a[0][0],a[0][1],a[1][0],a[1][1] respectively, the upper left, upper right, lower left, lower right four grid color, for the top and bottom two faces, when you face the cube before this face, overlooking the upper and lower two Faces, a[0][ 0],A[0][1],A[1][0],A[1][1] Indicates the color of upper left, upper right, bottom left, bottom right, respectively. With the expression, the following is the part of the rotation, a little bit more careful on the line. The code is as follows:
#include <cstdio> #include <cstring> using namespace std;
	#define N-struct face {int a[2][2];
			void set (int val) {for (int i = 0; i < 2; ++i) {for (int j = 0; j < 2; ++j) {a[i][j] = val;
				}}}//Determine if the color of this face is all Val int ok (int val) {for (int i = 0; i < 2; ++i) {for (int j = 0; j < 2; ++j) {
				if (a[i][j]! = val) {return 0;
	}}} return 1;

}}face[n];
Counter-clockwise to the rotated four polygon int u[] = {4, 1, 5, 0};
int f[] = {4, 2, 5, 3};
int r[] = {0, 2, 1, 3};

Char Str[n];
		Determines whether to restore int check (void) {for (int i = 0; i < 6; ++i) {if (!face[i].ok (i)) {return 0;
}} return 1;
	} void Up (void) {int tmp[2];
	Tmp[0] = face[u[3]].a[0][0];
	TMP[1] = face[u[3]].a[0][1];
		for (int i = 2; I >= 0; i.) {for (int j = 0; j < 2; ++j) {face[u[i + 1]].a[0][j] = Face[u[i]].a[0][j];
	}} Face[u[0]].a[0][0] = tmp[0];
	FACE[U[0]].A[0][1] = tmp[1];
	Face t = face[2];
	Face[2].a[0][0] = t.a[1][0]; FACE[2].A[0][1] = t.a[0][0];
	Face[2].a[1][0] = t.a[1][1];
FACE[2].A[1][1] = t.a[0][1];
	} void Front (void) {int tmp[2];
	Tmp[0] = face[f[3]].a[1][0];
	TMP[1] = face[f[3]].a[1][1];
	Face[f[3]].a[1][0] = face[f[2]].a[1][0];
	FACE[F[3]].A[1][1] = face[f[2]].a[0][0];
	Face[f[2]].a[1][0] = face[f[1]].a[1][1];
	Face[f[2]].a[0][0] = face[f[1]].a[1][0];
	FACE[F[1]].A[1][1] = face[f[0]].a[0][1];
	Face[f[1]].a[1][0] = face[f[0]].a[1][1];
	FACE[F[0]].A[0][1] = tmp[0];
	FACE[F[0]].A[1][1] = tmp[1];
	Face t = face[0];
	Face[0].a[0][0] = t.a[1][0];
	FACE[0].A[0][1] = t.a[0][0];
	Face[0].a[1][0] = t.a[1][1];
FACE[0].A[1][1] = t.a[0][1];
	} void Right (void) {int tmp[2];
	Tmp[0] = face[r[3]].a[0][1];
	TMP[1] = face[r[3]].a[1][1];
	FACE[R[3]].A[0][1] = face[r[2]].a[0][0];
	FACE[R[3]].A[1][1] = face[r[2]].a[1][0];
	Face[r[2]].a[0][0] = face[r[1]].a[1][1];
	Face[r[2]].a[1][0] = face[r[1]].a[0][1];
	FACE[R[1]].A[1][1] = face[r[0]].a[1][1];
	FACE[R[1]].A[0][1] = face[r[0]].a[0][1];
	FACE[R[0]].A[1][1] = tmp[0]; Face[r[0]].A[0][1] = tmp[1];
	Face t = face[5];
	Face[5].a[0][0] = t.a[1][0];
	FACE[5].A[0][1] = t.a[0][0];
	Face[5].a[1][0] = t.a[1][1];
FACE[5].A[1][1] = t.a[0][1];
	} int main (int argc, char *argv[]) {int len;
		while (scanf ("%d%s", &len, str)! = EOF) {//0-5 represents the front and rear left and right for (int i = 0; i < 6; ++i) {face[i].set (i);
		} int ans = 0;
					while (1) {to (int i = 0; i < len; ++i) {switch (Str[i]) {case ' U ': Up (); Case ' F ': Front ();
					Break Case ' R ': Right ();
				Break
			}} ++ans;
			if (check ()) {break;
	}} printf ("%d\n", ans);
} return 0; 
 }

Problem B:text Holes directly determine how many holes are in a given string, A,d,o,p,q,r has 11 holes and B has two holes. Code:
#include <iostream>
#include <string>

using namespace std;

int val[] = {1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
		};

int main (int argc, char *argv[])
{
	int t;
	CIN >> T;
	while (t--) {
		string s;
		Cin >> S;
		int len = S.length ();
		int ans = 0;
		for (int i = 0; i < len; ++i) {
			int idx = s[i]-' A ';
			Ans + = Val[idx];
		}
		cout << ans << endl;
	}
	
	return 0;
}

Problem C: Fibonacci number is basically a math problem, no difficulty, because the given K is too big (10^10000), this k with 64-bit integer can not save, only use String to save.  The Fibonacci number is defined as f (n) =f (n-1) +f (n-2), (n>=2), where F (0) =0,f (1) = 1. We are based on odd + odd = even, odd + even = odd, even + even = even, easy to roll out when and only if K is a multiple of 3, f[k] is even. Judging whether a number is a multiple of 3, the primary school method is to add up all the digits to see if this and can be divisible by 3, and the other method is to add edge to the remainder, and finally see if the remainder is 0. The code is as follows:
#include <iostream>
#include <cstring>

using namespace std;

Char mp[][10] = {"YES", "No", "no"};

int main (int argc, char *argv[])
{
	int t;
	CIN >> T;
	while (t--) {
		string s;
		Cin >> S;
		int len = S.length ();
		int ans = 0;
		for (int i = 0; i < len; ++i) {
			ans = (ans * + s[i]-' 0 ')% 3;
		}
		cout << Mp[ans] << Endl;
	}
	
	return 0;
}

Problem D: The sequel to Tang's seniors ' honeymoon to determine if there are such two numbers, A, B, their greatest common divisor and least common multiple are m,n respectively. Given the M,n, a, B, if there are multiple sets of solutions, the output of a value of the smallest. M is a, B greatest common divisor, we set A=CM,B=DM, because A*b=m*n, so there is a*b=c*d*m*m=m*n, we got the n=c*d*m, so that n must be a multiple of M, and N is a multiple of m also must exist solution, because requires a minimum, so desirable c= 1, then get the a=m,b=n, that is, directly determine whether n is a multiple of M, if it is, directly output these two numbers, otherwise output the given string. But pay attention to the input requirements given by the topic. Code:
#include <iostream>

using namespace std;

int main (int argc, char *argv[])
{
	int t;
	while (cin >> t) {while
		(t--) {
			Long long A, b;
			Cin >> a >> b;
			if (b% A = = 0) {
				cout << a << "" << b << endl;
			} else {
				cout << "senior Tang is so smart. "<< Endl;}}
	}
	
	return 0;
}

Problem E: Xiaohua in effort the problem is one of the longest common subsequence (LCS), but the amount of data is too large to use the normal O (n^2) algorithm, to seek a more efficient algorithm. The following algorithm converts LCS into the longest ascending subsequence (LIS), and the LIS has an O (NLOGN) algorithm to solve this problem. For two sequences A[1...N] and B[1...M], we first assume that the elements in a do not recur in B, that is, either none or only one. We first find out the position of the element in A in B (if there is no assumption that the position is infinity or simply do not record it), then arrange it in order, and then to the sequence of the LIS, the length of the two series is the LCS length. If the elements in a can recur in B, find all the locations, sort them in descending order, and then write them down sequentially, and the rest is the LIS. In fact, this title is the original question on the White Book, on page 66. Prove it, and realize it. The code is as follows:
#include <iostream> #include <cstring> #include <algorithm> using namespace std;

#define N 80005 int num1[n], num2[n], idx[n], p[n], c[n], CNT, Len;
	int get (int pos) {int l = 1;
	int r = len-1;
		while (L <= r) {int mid = (L + r) >> 1;
		if (C[mid] < Idx[pos] && C[mid + 1] >= Idx[pos]) {return mid + 1;
		} else if (C[mid] < Idx[pos]) {L = mid + 1;
		} else {r = mid-1;
}}//Can not find the update length of 1,//or else will not be this step return 1;
	} int lis (void) {len = 0;
	C[0] =-1;
		for (int i = 0; i < cnt; ++i) {if (Idx[i] > C[len]) {C[++len] = Idx[i];
			} else {int pos = get (i);
		C[pos] = Idx[i];
}} return len; The longest common subsequence (LCS) is converted to the longest ascending subsequence (LIS) * To find the position of the element in the first sequence in order of the second sequence * (if there are multiple positions, the position is descending, the reason for descending is that the element in a * This position can only be selected once), * into a sequence,
 The length of the lis,lis for this position sequence is the length of the two-string LCS.
	*/int main (int argc, char *argv[]) {int n, x, y;
	int k = 0;
		while (CIN >> n >> x >> y) {memset (P,-1, sizeof (p)); for (int i =0; i < x;
		++i) {cin >> num1[i];
		} for (int i = 0; i < y; ++i) {cin >> num2[i];
		} for (int i = 0; i < y; ++i) {P[num2[i]] = i;
		} cnt = 0;
			for (int i = 0; i < x; ++i) {if (P[num1[i]] >= 0) {idx[cnt++] = p[num1[i]];
		}} ++k;
	cout << "Case" << k << ":" << lis () << Endl;
} return 0;
 }

Problem F: Looking for Happiness small L This problem is a bare point of judgment in a convex polygon, there are many methods, the simplest is to use the cross product, or a triangular area to calculate the direction. If a point is in a convex polygon or edge of a M-bar, then this point can be in turn and the M-vertex composed of M-triangles (there may be a triangular three-point collinear, but this does not affect the conclusion), respectively, the area of the triangle (not the direction of the area), the M area is added up, is the area of If this point is not inside or on the edge of a convex polygon, then the M area will be more than the actual area. But the area to be added up is the actual area (the area can be offset), at the same time, this area of the way suitable for concave polygons. Then we can determine whether this point is inside or on the edge of a convex polygon based on this. This area-judging method is not suitable for concave polygons. Code:
#include <cstdio> #include <algorithm> using namespace std;
	#define N-A struct point {int x, y;
		Point (void) {this->x = 0;
	this->y = 0;
		} point (int a, int b) {this->x = A;
	This->y = b;
	} int input (void) {return scanf ("%d%d", &x, &y);

}}pt[n];
	int Getarea (Point A, point B, point C) {int TMP1 = a.x * b.y + c.x * a.y + b.x * C.Y;
	
	int TMP2 = c.x * b.y + a.x * c.y + b.x * A.Y;
Return ABS (TMP1-TMP2); }//If the cross product is positive, indicating that the OAB three points are in counter-clockwise//if negative, indicating that the OAB three points are aligned clockwise//if 0, the OAB three points collinear//and the meaning of the cross product is three times the forward area of the triangle consisting of the OAB twice points//Because all the points here are integers,
	Directly calculate the area of twice times the line//do not use floating point number, the area of twice times is always an integer//and the top Getarea is the same, but the top is expanded int cross (point O, point A, point B) {int x1 = a.x-o.x;
	int y1 = A.Y-O.Y;
	int x2 = b.x-o.x;
	
	int y2 = b.y-o.y;
Return ABS (x1 * y2-x2 * y1);
	} int main (void) {int n, m;
	Point S;
		while (S.input ()! = EOF) {scanf ("%d%d", &n, &m);
		int ans = 0; for (int i = 0, i < n; ++i) {for (int j = 0; j < m; ++j) {PT[J].INPUT ();
			} int area1 = 0;
			int area2 = 0;
			PT[M] = pt[0];
				for (int j = 0; j < m; ++j) {//Area1 + = Getarea (s, pt[j], pt[j + 1]); 
			Area1 + = Cross (s, Pt[j], pt[j + 1]);
				} for (int j = 0; j < m; ++j) {//Area2 + = Getarea (Pt[0], pt[j], pt[j + 1]);
			Area2 + = Cross (Pt[0], pt[j], pt[j + 1]);
			} if (area1 = = area2) {ans = i + 1;
	}} printf ("%d\n", ans);
} return 0; }

Problem G: Running plan the problem is to minimize the distance between all nodes of the path, first consider multiple edges, if a to B has multiple edges, we can discard the long edge, select the long edge may make the maximum size, and select the short edge is either unchanged, or the maximum value is smaller, so the choice of short edge than the selection of long edge. Secondly, the path of all nodes must be a path on the smallest spanning tree; if it is not a tree, we can generate a minimal spanning tree, which ensures that all nodes are connected and that the path maximum is minimized, and if the tree is not the smallest spanning tree, then we can replace it with the smallest spanning tree, This will make certain edges more optimal. Using the algorithm of minimum spanning tree to write, the Kruskal algorithm is easy to implement. When merging edges, look at the number of nodes on each side, multiply, is the current edge for the longest distance of the number of paths, so and when the collection merge to record the number of nodes with n as the root node, and record the number of paths with this edge for the longest distance. At the same time the longest distance is also the smallest. Finally, the answer is to calculate the maximum and minimum worth of the minimum value for the longest distance. It is important to note that because A->b and b->a are different, the number of final records is multiplied by 2. The code is as follows:
#include <cmath> #include <ctime> #include <cctype> #include <climits> #include <cstdio> # Include <cstdlib> #include <cstring> #include <map> #include <set> #include <queue> #inclu De <stack> #include <string> #include <vector> #include <sstream> #include <iostream> # Include <algorithm> #define INF (INT_MAX/10) #define CLR (arr, Val) memset (arr, Val, sizeof (arr)) #define PB Push_
Back #define SZ (a) ((int) (a). Size ()) using namespace Std;
typedef set<int> SI;
typedef vector<int> VI;
typedef map<int, Int> Mii;

typedef long Long LL;

Const double ESP = 1e-5;
	#define N 1010 struct Node {int u, V, D;
	void input (void) {scanf ("%d%d%d", &u, &v, &d);

}}node[n];

int n, M, C[n], d[n], ans[n], num[n];

BOOL CMP (Node A, Node B) {return A.D < B.D;}
	int find (int n) {if (c[n] = = N) {return n;
	} else {return c[n] = find (C[n]); }} int main (int argc, Char *argv[]) {int t;
	scanf ("%d", &t);
		while (t--) {scanf ("%d%d", &n, &m);
		for (int i = 0; i < m; ++i) {node[i].input ();
		} Sort (node, node + M, CMP);
			for (int i = 1; I <= n; ++i) {c[i] = i;
		Num[i] = 1;
		} int cnt = 0;
			for (int i = 0; i < m; ++i) {int T1 = find (NODE[I].U);
			int t2 = FIND (NODE[I].V);
			int sum = NUM[T1] + num[t2];
				if (t1! = t2) {C[t1] = t2;
				D[CNT] = NODE[I].D;
				ANS[CNT] = num[t1] * NUM[T2];
				NUM[T1] = sum;
				NUM[T2] = sum;
			++cnt;
		}} int mn = d[0];
		int mx = d[cnt-1];
		int MNC = 0;
		int MXC = 0;
			for (int i = 0; i < cnt; ++i) {if (d[i] = = MN) {MNC + = Ans[i];
			} else {break;
			}} for (int i = cnt-1; I >= 0; i.) {if (d[i] = = mx) {MXC + = Ans[i];
			} else {break;
	}} printf ("%d%d\n", 2 * MNC, 2 * MXC);
} return 0; }

Problem H:xq's puzzle asks for an even number of 1 to N and the code:
#include <cstdio>
#include <cstring>
 
using namespace std;
 
#define N-ary
 
int dp[n];
 
int main (void)
{
    memset (DP, 0, sizeof (DP));
    DP[1] = 0;
    for (int i = 2; I <=; ++i) {
        dp[i] = dp[i-1];
        if (i% 2 = = 0) {
            Dp[i] + = i;
        }
    }
    int n;
    while (scanf ("%d", &n)! = EOF) {
        printf ("%d\n", Dp[n]);
    }
     
    return 0;
}


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.