灵动ICPC冬令营基础-2

A - Maya Calendar

题目

During his last sabbatical, professor M. A. Ya made a surprising discovery about the old Maya calendar. From an old knotted message, professor discovered that the Maya civilization used a 365 day long year, called Haab, which had 19 months. Each of the first 18 months was 20 days long, and the names of the months were pop, no, zip, zotz, tzec, xul, yoxkin, mol, chen, yax, zac, ceh, mac, kankin, muan, pax, koyab, cumhu. Instead of having names, the days of the months were denoted by numbers starting from 0 to 19. The last month of Haab was called uayet and had 5 days denoted by numbers 0, 1, 2, 3, 4. The Maya believed that this month was unlucky, the court of justice was not in session, the trade stopped, people did not even sweep the floor.

For religious purposes, the Maya used another calendar in which the year was called Tzolkin (holly year). The year was divided into thirteen periods, each 20 days long. Each day was denoted by a pair consisting of a number and the name of the day. They used 20 names: imix, ik, akbal, kan, chicchan, cimi, manik, lamat, muluk, ok, chuen, eb, ben, ix, mem, cib, caban, eznab, canac, ahau and 13 numbers; both in cycles.

Notice that each day has an unambiguous description. For example, at the beginning of the year the days were described as follows:

1 imix, 2 ik, 3 akbal, 4 kan, 5 chicchan, 6 cimi, 7 manik, 8 lamat, 9 muluk, 10 ok, 11 chuen, 12 eb, 13 ben, 1 ix, 2 mem, 3 cib, 4 caban, 5 eznab, 6 canac, 7 ahau, and again in the next period 8 imix, 9 ik, 10 akbal . . .

Years (both Haab and Tzolkin) were denoted by numbers 0, 1, : : : , where the number 0 was the beginning of the world. Thus, the first day was:

Haab: 0. pop 0

Tzolkin: 1 imix 0
Help professor M. A. Ya and write a program for him to convert the dates from the Haab calendar to the Tzolkin calendar.
Input
The date in Haab is given in the following format:
NumberOfTheDay. Month Year

The first line of the input file contains the number of the input dates in the file. The next n lines contain n dates in the Haab calendar format, each in separate line. The year is smaller then 5000.
Output
The date in Tzolkin should be in the following format:
Number NameOfTheDay Year

The first line of the output file contains the number of the output dates. In the next n lines, there are dates in the Tzolkin calendar format, in the order corresponding to the input dates.
Sample Input

3
10. zac 0
11. pop 0
12. zac 1995

Sample Output

3
3 chuen 0
1 imix 0
9 cimi 2801

解析

在参考程序中,Haab历和Tzolkin历的月份,分别用字符串数组haab和tzolkin表示;
设Haab历的日期为year年month月date天,则这一日期从世界开始计起的天数current。
对于第current天来说,Tzolkin历的日期为year年的第num个时期内的第word天。由于Tzolkin历每年有260天(13个时期,每时期20天),因此若current % 260=0,则表明该天是Tzolkin历中某年最后一天,即year=current/260-1,num=13,word=20天;若current %260≠0,则year=current/260;num=(current % 13 == 0 ? 13 : current%13),word=(current - 1) % 20+1。

代码

#include <stdio.h>
#include <string.h>
char haab[19][10] = {"pop", "no", "zip", "zotz", "tzec", "xul", "yoxkin", "mol", "chen", "yax", "zac", "ceh", "mac", "kankin", "muan", "pax", "koyab", "cumhu", "uayet"};
char tzolkin[20][10] = {"imix", "ik", "akbal", "kan", "chicchan", "cimi", "manik", "lamat", "muluk", "ok", "chuen", "eb", "ben", "ix", "mem", "cib", "caban", "eznab", "canac", "ahau"};
int main() {
	int  i, j, n, day, year, sum;
	char month[10];
	while (~scanf("%d",&n)) {
		printf("%d\n",n);
		for (i = 0; i < n; ++ i) {
			scanf("%d. %s %d", &day, month, &year);
			for (j = 0; j < 19; ++ j)
				if (strcmp(haab[j], month)==0) {
					sum = year*365 + j*20 + day;
					break;
				}
				else continue;
			printf("%d %s %d\n",sum%13+1,tzolkin[sum%20],sum/260);	
		}
	}
	return 0;
}

B - Diplomatic License

题目

In an effort to minimize the expenses for foreign affairs the countries of the world have argued as follows. It is not enough that each country maintains diplomatic relations with at most one other country, for then, since there are more than two countries in the world, some countries cannot communicate with each other through (a chain of) diplomats.

Now, let us assume that each country maintains diplomatic relations with at most two other countries. It is an unwritten diplomatic “must be” issue that every country is treated in an equal fashion. It follows that each country maintains diplomatic relations with exactly two other countries.

International topologists have proposed a structure that fits these needs. They will arrange the countries to form a circle and let each country have diplomatic relations with its left and right neighbours. In the real world, the Foreign Office is located in every country’s capital. For simplicity, let us assume that its location is given as a point in a two-dimensional plane. If you connect the Foreign Offices of the diplomatically related countries by a straight line, the result is a polygon.

It is now necessary to establish locations for bilateral diplomatic meetings. Again, for diplomatic reasons, it is necessary that both diplomats will have to travel equal distances to the location. For efficiency reasons, the travel distance should be minimized. Get ready for your task!
Input
The input contains several testcases. Each starts with the number n of countries involved. You may assume that n>=3 is an odd number. Then follow n pairs of x- and y-coordinates denoting the locations of the Foreign Offices. The coordinates of the Foreign Offices are integer numbers whose absolute value is less than 1012. The countries are arranged in the same order as they appear in the input. Additionally, the first country is a neighbour of the last country in the list.
Output
For each test case output the number of meeting locations (=n) followed by the x- and y-coordinates of the locations. The order of the meeting locations should be the same as specified by the input order. Start with the meeting locations for the first two countries up to the last two countries. Finally output the meeting location for the n-th and the first country.
Sample Input

5 10 2 18 2 22 6 14 18 10 18
3 -4 6 -2 4 -2 6
3 -8 12 4 8 6 12

Sample Output

5 14.000000 2.000000 20.000000 4.000000 18.000000 12.000000 12.000000 18.000000 10.000000 10.000000
3 -3.000000 5.000000 -2.000000 5.000000 -3.000000 6.000000
3 -2.000000 10.000000 5.000000 10.000000 -1.000000 12.000000

Hint
Note that the output can be interpreted as a polygon as well. The relationship between the sample input and output polygons is illustrated in the figure on the page of Problem 1940. To generate further sample input you may use your solution to that problem.

解析

本题给出n个点的坐标,这n个点围城一个多边形,求这个多边形的n条边的中点坐标。最后一个中点坐标是输入的起点和终点的中点坐标。
用结构表示点的x和y坐标,由中点坐标公式给出两个相邻点的中点坐标。

代码

#include<cstdio>
struct loc{
	long long  x, y;
}first, last, now;
int main() {
	int n;
	while(scanf("%d",&n)!=EOF) {
		printf("%d ",n);
		scanf("%lld%lld",&first.x,&first.y);
		now=first; 
		for(int i=1;i<n;i++) {
			scanf("%lld %lld", &last.x, &last.y);
			printf("%.6f %.6f ",(last.x+now.x)/2.0,(last.y+now.y)/2.0);
			now=last;
	   }
	   printf("%.6f %.6f", (last.x+first.x)/2.0, (last.y+first.y)/2.0);
	   putchar('\n');
    }
	return 0;
}

C - “Accordian” Patience

题目

You are to simulate the playing of games of ``Accordian’’ patience, the rules for which are as follows:

Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate neighbour on the left, or matches the third card to the left, it may be moved onto that card. Cards match if they are of the same suit or same rank. After making a move, look to see if it has made additional moves possible. Only the top card of each pile may be moved at any given time. Gaps between piles should be closed up as soon as they appear by moving all piles on the right of the gap one position to the left. Deal out the whole pack, combining cards towards the left whenever possible. The game is won if the pack is reduced to a single pile.
Situations can arise where more than one play is possible. Where two cards may be moved, you should adopt the strategy of always moving the leftmost card possible. Where a card may be moved either one position to the left or three positions to the left, move it three positions.
Input
Input data to the program specifies the order in which cards are dealt from the pack. The input contains pairs of lines, each line containing 26 cards separated by single space characters. The final line of the input file contains a # as its first character. Cards are represented as a two character code. The first character is the face-value (A=Ace, 2-9, T=10, J=Jack, Q=Queen, K=King) and the second character is the suit (C=Clubs, D=Diamonds, H=Hearts, S=Spades).
Output
One line of output must be produced for each pair of lines (that between them describe a pack of 52 cards) in the input. Each line of output shows the number of cards in each of the piles remaining after playing ``Accordian patience’’ with the pack of cards as described by the corresponding pairs of input lines.
Sample Input

QD AD 8H 5S 3H 5H TC 4D JH KS 6H 8S JS AC AS 8D 2H QS TS 3S AH 4H TH TD 3C 6S
8C 7D 4C 4S 7S 9H 7C 5D 2S KD 2D QH JD 6D 9D JC 2C KH 3D QC 6C 9S KC 7H 9C 5C
AC 2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KC AD 2D 3D 4D 5D 6D 7D 8D TD 9D JD QD KD
AH 2H 3H 4H 5H 6H 7H 8H 9H KH 6S QH TH AS 2S 3S 4S 5S JH 7S 8S 9S TS JS QS KS

Sample Output

6 piles remaining: 40 8 1 1 1 1
1 piles remaining: 52

解析

本题给一副扑克牌,一共52张。首先,将扑克牌从左往右一张张地排列。然后从左往右遍历,如果该牌和左边第一张牌或左边第三张牌相匹配,那么就将这张牌移到被匹配的牌上,形成牌堆;每次只能移动每堆牌最上面一张牌。两张牌匹配条件是面值相同或者花色相同。每次移动一张牌后,还应检查牌堆,看有没有其他牌能往左移动;如果没有,遍历下一张牌,直到不能移动牌为止。最后,输出每一堆扑克牌中剩余的扑克牌的数量。
在参考程序中,扑克牌用带指针变量的结构体表示,其中两个字符变量a和b分别表示扑克牌的面值和花色,指针变量pre和post分别指向从左往右的顺序中的前一张牌和后一张牌,而指针变量down则指向所在牌堆的下一张牌。这副扑克牌表示为一个三相链表,每一个牌堆用线性链表表示,而在牌堆顶部的牌,其pre和post分别指向前一个牌堆顶部的牌和后一个牌堆顶部的牌。
本题根据题目给定的规则,模拟发牌和移动牌的过程。这里要注意, 根据题意,应先比较左边第三张,然后,再比较左边第一张。

代码

#include<cstdio>
using namespace std;
const int N = 55;
char s[N][N][N];
int pre[N], last[N], mp[N], sum[N], ans[N];
int getp3(int x) {
	int p1 = pre[x], p2 = pre[p1], p3 = pre[p2];
	return p3;
}
int getp1(int x) {
	int p1 = pre[x];
	return p1;
}
int main() {
	while(1) {
		scanf("%s", s[1][1]);
		if(s[1][1][0] == '#') break;
		last[1] = 2; sum[1] = 1; last[0] = 1;
		for(int i = 2; i <= 52; i++) {
			scanf("%s", s[i][1]);
			pre[i] = i - 1;
			last[i] = i + 1;
			sum[i] = 1;
		}
		for(int i = 2; i <= 52; i = last[i]) {
			int p = getp3(i);
			if(p > 0 && (s[p][sum[p]][0] == s[i][sum[i]][0] || s[p][sum[p]][1] == s[i][sum[i]][1])) {
				sum[p]++;
				s[p][sum[p]][0] = s[i][sum[i]][0];
				s[p][sum[p]][1] = s[i][sum[i]][1];
				sum[i]--;
				if(sum[i] == 0) {
					last[pre[i]] = last[i];
					pre[last[i]] = pre[i];
				}
				i = p - 1;
				continue;
			}
			p = getp1(i);
			if(p > 0 && (s[p][sum[p]][0] == s[i][sum[i]][0] || s[p][sum[p]][1] == s[i][sum[i]][1])) {
				sum[p]++;
				s[p][sum[p]][0] = s[i][sum[i]][0];
				s[p][sum[p]][1] = s[i][sum[i]][1];
				sum[i]--;
				if(sum[i] == 0) {
					last[pre[i]] = last[i];
					pre[last[i]] = pre[i];
				}
				i = p - 1;
				continue;
			}
		}
		int cnt = 0;
		for(int i = 1; i <= 52; i++) {
			if(sum[i]) ans[cnt++] = sum[i];
		}
		printf("%d piles remaining: %d", cnt, ans[0]);
		for(int i = 1; i < cnt; i++) {
			printf(" %d", ans[i]);
		}
		printf("\n");
	}
	return 0;
}

D - Broken Keyboard (a.k.a. Beiju Text)

题目

You’re typing a long text with a broken keyboard. Well it’s not so badly broken. The only problem
with the keyboard is that sometimes the “home” key or the “end” key gets automatically pressed
(internally).
You’re not aware of this issue, since you’re focusing on the text and did not even turn on the
monitor! After you finished typing, you can see a text on the screen (if you turn on the monitor).
In Chinese, we can call it Beiju. Your task is to find the Beiju text.
Input
There are several test cases. Each test case is a single line containing at least one and at most 100,000
letters, underscores and two special characters ‘[’ and ‘]’. ‘[’ means the “Home” key is pressed
internally, and ‘]’ means the “End” key is pressed internally. The input is terminated by end-of-file
(EOF).
Output
For each case, print the Beiju text on the screen.
Sample Input

This_is_a_[Beiju]_text
[[]][][]Happy_Birthday_to_Tsinghua_University

Sample Output

BeijuThis_is_a__text
Happy_Birthday_to_Tsinghua_University

解析

本题题意:
对于每个输入的字符串,如果出现’ [ ‘,则输入光标就跳到字符串的最前面,如果出现’ ] ‘,则输入光标就跳到字符串的最后面。输出实际上显示在屏幕上的字符串。
将输入的字符串表示为链表,再输出。其中,每个字符为链表中的元素的数据,而指针指向按序输出的下一个元素。
用数组模拟链表链表:用数组next代替链表中的next指针,例如,第一个字符s[1]的下一个字符是s[2],则next[1]=2。此外,对于链表,第0个元素不储存数据,作为辅助头结点,第一个元素开始储存数据。
设置变量cur表示光标,cur不是当前遍历到的位置i,是表示位置i的字符应该插入在cur的右侧。如果当前字符为’ [ ‘,光标cur就跳到字符串的最前面,即cur=0;如果’ ] ',光标就跳到字符串的最后面,即cur=last,其中变量last保存当前字符串最右端的下标。
程序根据试题描述给出的规则进行模拟。

代码

#include <cstdio>
#include <cstring>
const int maxn=100005;
int last , cur, next[maxn];
char s[maxn];
int main ()
{
    while (scanf ("%s", s+1) !=EOF) {
        int n = strlen(s+1);
        last = cur = 0;
        next[0] = 0;
        for (int i = 1 ; i <= n ; ++i) {
            if (s[i] == '[') cur=0;
            else if (s[i] == ']') cur = last;
            else {
                next[i] = next[cur];
                next[cur] = i;
                if (cur==last) last=i;
                cur=i;
            }
        }
        for (int i = next[0]; i!=0;i=next[i]) printf("%c", s[i]);
    	printf("\n");
    }
    return 0;
}

E - Satellites

题目

在这里插入图片描述

The radius of earth is 6440 Kilometer. There are many Satellites and Asteroids moving around the earth. If two Satellites
create an angle with the center of earth, can you find out
the distance between them? By distance we mean both the
arc and chord distances. Both satellites are on the same orbit
(However, please consider that they are revolving on a circular
path rather than an elliptical path).
Input
The input file will contain one or more test cases.
Each test case consists of one line containing two-integer
s and a, and a string ‘min’ or ‘deg’. Here s is the distance of
the satellite from the surface of the earth and a is the angle
that the satellites make with the center of earth. It may be in minutes (′) or in degrees (◦). Remember
that the same line will never contain minute and degree at a time.
Output
For each test case, print one line containing the required distances i.e. both arc distance and chord
distance respectively between two satellites in Kilometer. The distance will be a floating-point value
with six digits after decimal point.
Sample Input

500 30 deg
700 60 min
200 45 deg

Sample Output

3633.775503 3592.408346
124.616509 124.614927
5215.043805 5082.035982

解析

在这里插入图片描述

代码

#include <cstdio>
#include <cmath>
const double PI=acos(-1.0);
const double r=6440;
int main() {
	double s, a, jl, hc, ang;
	char   c[5];
	while (~scanf("%lf %lf %s", &s, &a, c)) {
		if (c[0]=='m') a/=60;
		if ( a > 180 ) a=360-a;
		ang=a*PI/180;
		jl=2.0*(s+r)*sin(ang/2);
		hc=ang*(s+r);
		printf("%.6lf %.6lf\n", hc, jl);
	}
	return 0;
}

F - Fourth Point !!

题目

Given are the (x, y) coordinates of the endpoints of two adjacent sides of a parallelogram. Find the
(x, y) coordinates of the fourth point.
Input
Each line of input contains eight floating point numbers: the (x, y) coordinates of one of the endpoints of the first side followed by the (x, y) coordinates of the other endpoint of the first side, followed by the (x, y) coordinates of one of the endpoints of the second side followed by the (x, y) coordinates of the other endpoint of the second side. All coordinates are in meters, to the nearest mm. All coordinates are between −10000 and +10000. Input is terminated by end of file.
Output
For each line of input, print the (x, y) coordinates of the fourth point of the parallelogram in meters, to the nearest mm, separated by a single space.
Sample Input

0.000 0.000 0.000 1.000 0.000 1.000 1.000 1.000
1.000 0.000 3.500 3.500 3.500 3.500 0.000 1.000
1.866 0.000 3.127 3.543 3.127 3.543 1.412 3.145

Sample Output

1.000 0.000
-2.500 -2.500
0.151 -0.398

解析

给出平行四边形中两条相邻边的端点坐标,求第4个点的坐标。要注意的是,两条相邻边的端点坐标,会有两个点的坐标是重复的;因此,要判定哪两个点的坐标是重复的。
设给出的平行四边形中两条相邻边的端点坐标为(x0, y0),(x1, y1),(x2, y2)和(x3, y3),(x0, y0)= (x3, y3),求第4个点的坐标(xa, yb),则有xa-x2= x1-x0,ya-y2= y1-y0;得xa=x2+x1-x0,ya= y2+y1-y0
在参考C++程序中,使用交换函数swap。交换函数swap包含在命名空间std 里面,使用swap,不用心交换变量精度的缺失,无需构造临时变量,也不会增加空间复杂度。

代码

#include <cstdio>
typedef struct Cord{
	double x, y;
}Cord;
int main() {
	Cord a, b, c, d, e;
	while(~scanf("%lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y)) {
		scanf("%lf %lf %lf %lf", &c.x, &c.y, &d.x, &d.y);
		if(a.x==c.x&&a.y==c.y) e.x=b.x+d.x-a.x, e.y=b.y+d.y-a.y;
		if(a.x==d.x&&a.y==d.y) e.x=b.x+c.x-d.x, e.y=b.y+c.y-d.y;
		if(b.x==d.x&&b.y==d.y) e.x=a.x+c.x-d.x, e.y=a.y+c.y-d.y;
		if(b.x==c.x&&b.y==c.y) e.x=a.x+d.x-c.x, e.y=a.y+d.y-c.y;
		printf("%.3lf %.3lf\n", e.x, e.y);
	}
	return 0;
}

G - The Circumference of the Circle

题目

To calculate the circumference of a circle seems to be an easy task - provided you know its diameter. But what if you don’t?

You are given the cartesian coordinates of three non-collinear points in the plane.
Your job is to calculate the circumference of the unique circle that intersects all three points.
Input
The input will contain one or more test cases. Each test case consists of one line containing six real numbers x1,y1, x2,y2,x3,y3, representing the coordinates of the three points. The diameter of the circle determined by the three points will never exceed a million. Input is terminated by end of file.
Output
For each test case, print one line containing one real number telling the circumference of the circle determined by the three points. The circumference is to be printed accurately rounded to two decimals. The value of pi is approximately 3.141592653589793.
Sample Input

0.0 -0.5 0.5 0.0 0.0 0.5
0.0 0.0 0.0 1.0 1.0 1.0
5.0 5.0 5.0 7.0 4.0 6.0
0.0 0.0 -1.0 7.0 7.0 7.0
50.0 50.0 50.0 70.0 40.0 60.0
0.0 0.0 10.0 0.0 20.0 1.0
0.0 -500000.0 500000.0 0.0 0.0 500000.0

Sample Output

3.14
4.44
6.28
31.42
62.83
632.24
3141592.65

解析

此题的关键是求出与距离d的公式。设3个点分别为(xa, ya),(xb, yb)和(xc, yc), 利用数学公式关系联立方程推导出距离d。
本题采用初等几何知识解题。
在这里插入图片描述

代码

#include<cstdio>
#include<cmath>
double xa,ya,xb,yb,xc,yc,p;
double Dis(double x,double y,double xx,double yy){
	return sqrt(pow(x-xx,2)+pow(y-yy,2));
}
int main() {
	double a, b, c, d, p, s;
	while(~scanf("%lf%lf%lf%lf%lf%lf", &xa, &ya, &xb, &yb, &xc, &yc)) {
		a = Dis(xa,ya,xb,yb);
		b = Dis(xb,yb,xc,yc);
		c = Dis(xa,ya,xc,yc);
		p = (a+b+c)/2;
		s = sqrt(p*(p-a)*(p-b)*(p-c));
		d = a*b*c/2.0/s;
		printf("%.2f\n", d*acos(-1.0));
	}
return 0;
}

H - Titanic

题目

It is a historical fact that during the legendary voyage of “Titanic” the wireless telegraph machine had delivered 6 warnings about the danger of icebergs. Each of the telegraph messages described the point where an iceberg had been noticed. The first five warnings were transferred to the captain of the ship. The sixth one came late at night and a telegraph operator did not notice that the coordinates mentioned were very close to the current ship’s position.

Write a program that will warn the operator about the danger of icebergs!
Input

The input messages are of the following format:
Message #<n>.

Received at <HH>:<MM>:<SS>. 

Current ship's coordinates are 

<X1>^<X2>'<X3>" <NL/SL> 

and <Y1>^<Y2>'<Y3>" <EL/WL>.

An iceberg was noticed at 

<A1>^<A2>'<A3>" <NL/SL> 

and <B1>^<B2>'<B3>" <EL/WL>.

Here <n> is a positive integer, <HH>:<MM>:<SS> is the time of the message reception,
 <X1>^<X2>'<X3>" <NL/SL> and <Y1>^<Y2>'<Y3>" <EL/WL> means
  "X1 degrees X2 minutes X3 seconds of North (South) latitude 
  and Y1 degrees Y2 minutes Y3 seconds of East (West) longitude."

Output

Your program should print to the output file message in the following format:
The distance to the iceberg: <s> miles.
Where <s> should be the distance between the ship and the iceberg, 
(that is the length of the shortest path on the sphere between the ship and the iceberg). 
This distance should be printed up to (and correct to) two decimal digits. 
If this distance is less than (but not equal to!) 100 miles the program should print one more line with the text:
DANGER!

Sample Input

Message #513.
Received at 22:30:11. 
Current ship's coordinates are 
41 ^ 46 ' 00 " NL 
and 50 ^ 14'00" WL.
An iceberg was noticed at
41^14'11" NL 
and 51^09'00" WL.

Sample Output

The distance to the iceberg: 52.04 miles.
DANGER!

Hint
For simplicity of calculations assume that the Earth is an ideal sphere with the diameter of 6875 miles completely covered with water. Also you can be sure that lines in the input file break exactly as it is shown in the input samples. The ranges of the ship and the iceberg coordinates are the same as the usual range for geographical coordinates, i.e. from 0 to 90 degrees inclusively for NL/SL and from 0 to 180 degrees inclusively for EL/WL.

解析

本题要求您计算一个球体上两点之间的距离。直接采用计算球体上距离的公式。如果距离小于100英里,则输出:“DANGER!”已知球体上两点A和B的纬度和经度,分别为(wA, jA)和(wB, jB),计算A和B之间的距离公式:dist(A, B) =R*arccos(cos(wA)*cos(wB)*cos(jA-jB)+sin(wA)*sin(wB));其中R是球
体的半径,默认’N’和’E’为正方向,'S’和’W’为负方向。
本题的输入的处理相对麻烦,先把经纬度的度、分、秒转换成度,再根据东西经,南北纬取正负号。在计算距离时,度转换为弧度;然后根据球上两点距离公式求船和冰山的距离。实现过程请参看参考程序。

代码

#include <cstdio>
#include <cmath>
const int maxn = 100;
char str[maxn];
double d, m, s, L1, L2, D1, D2;
double Dis(double l1, double d1, double l2, double d2)
{
    double r = 6875.0 / 2;
    double p = acos(-1.0);
    l1 *= p / 180.0; l2 *= p / 180.0;
    d1 *= p / 180.0; d2 *= p / 180.0;
    double d = r * sqrt(2 - 2 * (cos(l1) * cos(l2) * cos(d1 - d2) + sin(l1) * sin(l2)));
    return 2 * asin(d / (2 * r)) * r;
}
int main()
{
    while (~scanf("%*s%*s%*s%*s%*s%*s%*s%*s%*s"))
    {
        scanf("%lf^%lf'%lf\"%s", &d, &m, &s, &str);
        L1 = d + m / 60 + s / 3600; if (str[0] == 'S') L1 *= -1;
        scanf("%*s");
        scanf("%lf^%lf'%lf\"%s", &d, &m, &s, &str);
        D1 = d + m / 60 + s / 3600; if (str[0] == 'W') D1 *= -1;
        scanf("%*s%*s%*s%*s%*s");
        scanf("%lf^%lf'%lf\"%s", &d, &m, &s, &str);
        L2 = d + m / 60 + s / 3600; if (str[0] == 'S') L2 *= -1;
        scanf("%*s");
        scanf("%lf^%lf'%lf\"%s", &d, &m, &s, &str);
        D2 = d + m / 60 + s / 3600; if (str[0] == 'W') D2 *= -1;
        scanf("%*s");
        double ans = Dis(L1, D1, L2, D2);
        printf("The distance to the iceberg: %.2lf miles.\n", ans);
        if (floor(ans * 100 + 0.5) < 100 * 100) printf("DANGER!\n")                                              ;
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值