吴永辉教授2021年讲课1-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.

题目大意:
给你一个Haab历,按照规则转换成Tzolkin历

思路:
Haab历和Tzolkin历的月份用字符串数组表示,日期用结构体来表示。
设Habb历的日期为y年m月d天,则这一日期从世界开始记起的天数为cnt。对于第cnt天来说,Tzolkin历的日期为y年的第num个时期内的第s天,由于Tzolkin历每年有260天(13个时期,每时期20天),因此若cnt%260=0,则表明该天是Tzolkin历中某年的最后一天,即y=cnt/260-1,num=13,s=20;否则y=cnt/260-1,num=(cnt%13==0?13:cnt%13),s=(cnt-1)%20+1。
代码:

#include<iostream>
#include<string.h>
using namespace std;
typedef long long ll;

string Haab[19]={"pop","no","zip","zotz","tzec","xul","yoxkin","mol","chen","yax","zac","ceh","mac","kankin","muan","pax","koyab","cumhu","uayet"};
string Tzolkin[20]={"imix","ik","akbal","kan","chicchan","cimi","manik","lamat","muluk","ok","chuen","eb","ben","ix","mem","cib","caban","eznab","canac","ahau"};

struct node{
	int year;
	string month;
	int date;
};

void convert(node &d){
	ll i,cnt,num,y=0;
	string s;
	for(i=0;i<20;i++){
		if(d.month==Haab[i]){
			break;
		}
	}
	cnt = d.year*365+i*20+d.date+1;
	if(cnt%13==0){
		num = 13;
	}
	else{
		num = cnt%13;
	}
	while((cnt-260)>0){
		y++;
		cnt-=260;
	}
	if(cnt==0){
		s = "ahau";
	}
	else{
		while((cnt-20)>0){
			cnt-=20;
		}
		if(cnt==0){
			s = "ahau";
		}
		else{
			s = Tzolkin[cnt-1];
		}
	}
	cout<<num<<" "<<s<<" "<<y<<endl;
}
int main(){
	ll i,n;
	char ch;
	cin>>n;
	node a[n+5];
	for(i=0;i<n;i++){
		//scanf("%d. %s %d",&a[i].date,&a[i].month,&a[i].year);
		cin>>a[i].date>>ch>>a[i].month>>a[i].year;
	}
	cout<<n<<endl;
	
	for(i=0;i<n;i++){
		convert(a[i]);
	}
	return 0;
}

B.Tic Tac Toe

Tic Tac Toe is a child’s game played on a 3 by 3 grid. One player, X, starts by placing an X at an unoccupied grid position. Then the other player, O, places an O at an unoccupied grid position. Play alternates between X and O until the grid is filled or one player’s symbols occupy an entire line (vertical, horizontal, or diagonal) in the grid.
We will denote the initial empty Tic Tac Toe grid with nine dots. Whenever X or O plays we fill in an X or an O in the appropriate position. The example below illustrates each grid configuration from the beginning to the end of a game in which X wins.
… X… X.O X.O X.O X.O X.O X.O
… … … … .O. .O. OO. OO.
… … … …X …X X.X X.X XXX
Your job is to read a grid and to determine whether or not it could possibly be part of a valid Tic Tac Toe game. That is, is there a series of plays that can yield this grid somewhere between the start and end of the game?

Input
The first line of input contains N, the number of test cases. 4N−1 lines follow, specifying N grid configurations separated by empty lines.

Output
For each case print “yes” or “no” on a line by itself, indicating whether or not the configuration could be part of a Tic Tac Toe game.

题目大意:
在一个3*3的网格上玩家X与玩家O交替下棋,'X’与’O’交替放置直到网格被占满,或者有一个玩家的符号在网格中占据了一行(垂直,水平,或对角),要求输入一个网格,问能否通过一系列步骤可以在游戏开始到结束之间产生这一网格。

思路:
由于玩家X先走且轮流执子,因此网格图为有效的三连棋游戏的一个步骤,一定同时呈现下述特征:.
1.‘O’的数目一定小于等于‘X’的数目。
2.如果‘X’的数目比‘O’多1个,那么不可能是玩家О赢了三连棋。
3.如果‘X’的数目和‘O’的数目相等,则不可能玩家X赢了三连棋。
也就是说,网格图为无效的三连棋游戏的一个步骤,至少呈现下述5个特征之一:
1.O”的个数大于X”的个数。
2.‘X”的个数至少比‘O’的个数多2
3.已经判出玩家O和玩家X同时赢。
4.已经判出玩家O赢,但‘O’的个数与‘X’的个数不等;
5.已经判出玩家X赢,但双方棋子个数相同:
否则网格图为有效的三连棋游戏的一个步骤。
代码:

#include<iostream>
using namespace std;

char a[4][4];

bool judge(char c){
	int i,j;
	for(i=0;i<3;i++){
		for(j=0;j<3;j++){
			if(a[i][j]==c){
				continue;
			}
			else{
				break;
			}
		}
		if(j==3){
			return 1;
		}
		
		for(j=0;j<3;j++){
			if(a[j][i]==c){
				continue;
			}
			else{
				break;
			}
		}
		if(j==3){
			return 1;
		}
	}
	for(i=0;i<3;i++){
		if(a[i][i]==c){
			continue;
		}
		else{
			break;
		}
	}
	if(i==3){
		return 1;
	}
	for(i=0;i<3;i++){
		if(a[i][2-i]==c){
			continue;
		}
		else{
			break;
		}
	}
	if(i==3){
		return 1;
	}
	
	return 0;
}

int main(){
	int i,j,n,x,o;
	int flag=0;
	cin>>n;
	getchar();
	while(n--){
		x=o=0;
		for(i=0;i<3;i++){
			cin>>a[i];
		}
		flag = 1;
		for(i=0;i<3;i++){
			for(j=0;j<3;j++){
				if(a[i][j]=='X')
					x++;
				else if(a[i][j]=='O')
					o++;
			}
		}
		
		if(judge('X')&&judge('O')){
			flag=0;
		}
		else if(judge('X')&&x==o){
			flag=0;
		}
		else if(o>x||x-o>1){
			flag = 0;
		}
		else if((judge('O')&&x!=o)){
			flag=0;
		}
		else if(judge('X')&&x==o){
			flag=0;
		}
		
		if(flag){
			printf("yes\n");
		}
		else{
			printf("no\n");
		}			
	}
	return 0;
}

C. Function Run Fun

We all love recursion! Don’t we?
Consider a three-parameter recursive function w(a,b,c):
if a≤0 or b≤0 or c≤0, then w(a,b,c) returns:
1
if a>20 or b>20 or c>20, then w(a,b,c) returns:
w(20,20,20)
if a<b and b<c, then w(a,b,c) returns:
w(a,b,c−1)+w(a,b−1,c−1)−w(a,b−1,c)
otherwise it returns:
w(a−1,b,c)+w(a−1,b−1,c)+w(a−1,b,c−1)−w(a−1,b−1,c−1)
This is an easy function to implement. The problem is, if implemented directly, for moderate values of a,b and c (for example, a=15, b=15, c=15), the program takes hours to run because of the massive recursion.

Input
The input for your program will be a series of integer triples, one per line, until the end-of-file flag of -1 -1 -1. Using the above technique, you are to calculate w(a,b,c) efficiently and print the result.

Output
Print the value for w(a,b,c) for each triple.

题目大意:
根据题目中给出的公式求一个三参数的递归函数。

思路:
对于取中间值的a、b和c,由于大量递归,程序运行非常耗时。所以,本题的递归函数计算采用记忆化递归进行计算,用一个三维的数组f来记忆递归的结果,f[a][b][c]用于记忆w(a, b, c)的返回值。
代码:

#include<iostream>
#include<string.h>
using namespace std;
const int n=20;

int x[n+1][n+1][n+1]={0};

int f(int a,int b,int c){
	int ans;
	if(a<=0||b<=0||c<=0){
		return 1;
	}
	if(a>n||b>n||c>n){
		return f(n,n,n);
	}
	if(x[a][b][c]!=0){
		return x[a][b][c];
	}
	if(a<b&&b<c){
		ans = f(a,b,c-1)+f(a,b-1,c-1)-f(a,b-1,c);
		return  x[a][b][c]=ans;
	}
	ans = f(a-1,b,c)+f(a-1,b-1,c)+f(a-1,b,c-1)-f(a-1,b-1,c-1);
	return x[a][b][c]=ans;
} 

int main(){
	int a,b,c;
	while(scanf("%d %d %d",&a,&b,&c)!=EOF){
		if(a==-1&&b==-1&&c==-1){
			break;
		}
		else{
			printf("w(%d, %d, %d) = %d\n",a,b,c,f(a,b,c));
		}
	}
	return 0;
}

D. A Contesting Decision

Judging a programming contest is hard work, with demanding contestants, tedious decisions,and monotonous work. Not to mention the nutritional problems of spending 12 hours with only donuts, pizza, and soda for food. Still, it can be a lot of fun.
Software that automates the judging process is a great help, but the notorious unreliability of some contest software makes people wish that something better were available. You are part of a group trying to develop better, open source, contest management software, based on the principle of modular design.
Your component is to be used for calculating the scores of programming contest teams and determining a winner. You will be given the results from several teams and must determine the winner.
Scoring
There are two components to a team’s score. The first is the number of problems solved. The second is penalty points, which reflects the amount of time and incorrect submissions made before the problem is solved. For each problem solved correctly, penalty points are charged equal to the time at which the problem was solved plus 20 minutes for each incorrect submission. No penalty points are added for problems that are never solved.
So if a team solved problem one on their second submission at twenty minutes, they are charged 40 penalty points. If they submit problem 2 three times, but do not solve it, they are charged no penalty points. If they submit problem 3 once and solve it at 120 minutes, they are charged 120 penalty points. Their total score is two problems solved with 160 penalty points.
The winner is the team that solves the most problems. If teams tie for solving the most problems,then the winner is the team with the fewest penalty points.

Input
For the programming contest your program is judging, there are four problems. You are guaranteed that the input will not result in a tie between teams after counting penalty points.
Line 1 < n Teams >
Line 2 - n+1 < Name > < p1 Time > < p2 Sub > < p2 Time > … < p4 Time >

The first element on the line is the team name, which contains no whitespace. Following that, for each of the four problems, is the number of times the team submitted a run for that problem and the time at which it was solved correctly (both integers). If a team did not solve a problem, the time will be zero. The number of submissions will be at least one if the problem was solved.

Output
The output consists of a single line listing the name of the team that won, the number of problems they solved, and their penalty points.

题目大意:
给出参赛队伍在比赛中的情况和记分规则,要求你计算每个队伍的分数并确定冠军。

思路:
用结构体实现,结构体里包含参赛队名,4道题的提交次数,解题时间,解题数以及总罚时。
根据读入的队名,4道题的提交次数和解题时间,计算出每个队的解题数和总罚时,依次处理n个参赛队的信息,若当前队解题数最多或者同为目前最高解题数但罚时最少,则将当前队暂设为冠军队,记下队名,解题数和罚时,最终处理完后即得到答案。
代码:

#include<iostream>
#include<string.h>
using namespace std;
typedef long long ll;

struct node{
	string name;
	int sub[4];
	int time[4];
	int cnt;
	int t;
};
int main(){
	int i,j,n,cnt,t;
	string name;
	node team[1005];
	cin>>n;
	for(i=0;i<n;i++){
		cin>>team[i].name;
		for(j=0;j<4;j++){
			cin>>team[i].sub[j]>>team[i].time[j];
			team[i].cnt = team[i].t = 0;
		}
		for(j=0;j<4;j++){
			if(team[i].time[j]>0){
				team[i].cnt++;
				team[i].t = team[i].t + team[i].time[j]+(team[i].sub[j]-1)*20;
			}
		}
	}
	cnt = 0;
	t = 20000000;
	for(i=0;i<n;i++){
		if((team[i].cnt>cnt)||(team[i].cnt==cnt&&team[i].t<t)){
			name = team[i].name;
			cnt = team[i].cnt;
			t = team[i].t;
		}
	}
	cout<<name<<" "<<cnt<<" "<<t;
	return 0;
}

F. 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.

题目大意:
给出平面上的3个非贡献点的笛卡尔坐标,要求计算与这三个点相交的唯一圆的周长。

思路:
在这里插入图片描述
代码:

#include<iostream>
#include<math.h>
using namespace std;
#define PI 3.141592653589793
int main(){
	double x1,y1,x2,y2,x3,y3,a,b,c,p,s,d,ans;
	while(scanf("%lf %lf %lf %lf %lf %lf",&x1,&y1,&x2,&y2,&x3,&y3)!=EOF){
		//求三角形的三条边长 
		a = sqrt(pow(x1-x2,2)+pow(y1-y2,2));
		b = sqrt(pow(x1-x3,2)+pow(y1-y3,2));
		c = sqrt(pow(x2-x3,2)+pow(y2-y3,2));
		
		p = (a+b+c)/2;
		s = sqrt(p*(p-a)*(p-b)*(p-c)); //海伦公式-计算三角形面积 
		
		d = (a*b*c)/(2.0*s); //直径	
		ans = PI*d;
		printf("%.2lf\n",ans);
	}
	
	return 0;
}

H. Xu Xiake in Henan Province

Shaolin Monastery, also known as the Shaolin Temple, is a Chan (“Zen”) Buddhist temple in Dengfeng County, Henan Province. Believed to have been founded in the 55-th century CE, the Shaolin Temple is the main temple of the Shaolin school of Buddhism to this day.

Longmen Grottoes, are some of the finest examples of Chinese Buddhist art. Housing tens of thousands of statues of Buddha and his disciples, they are located 1212kilometres (7.57.5 mi) south of present-day Luoyang in Henan province.

White Horse Temple is, according to tradition, the first Buddhist temple in China, established in 6868 AD under the patronage of Emperor Ming in the Eastern Han dynasty capital Luoyang.

The Yuntai Mountain is situated in Xiuwu County, Jiaozuo, Henan Province. The Yuntai Geo Park scenic area is classified as an AAAAA scenic area by the China National Tourism Administration. Situated within Yuntai Geo Park, with a fall of 314 metres, Yuntai Waterfall is claimed as the tallest waterfall in China.

They are the most famous local attractions in Henan Province.
Now it’s time to estimate the level of some travellers. All travellers can be classified based on the number of scenic spots that have been visited by each of them.

A traveller that visited exactly 0 above-mentioned spot is a "Typically Otaku".
A traveller that visited exactly 1 above-mentioned spot is a "Eye-opener".
A traveller that visited exactly 2 above-mentioned spots is a "Young Traveller".
A traveller that visited exactly 3 above-mentioned spots is a "Excellent Traveller".
A traveller that visited all 4 above-mentioned spots is a "Contemporary Xu Xiake".

Please identify the level of a traveller.

Input
The input contains several test cases, and the first line contains a positive integer T indicating the number of test cases which is up to 104.

For each test case, the only one line contains four integers A1,A2,A3 and A4, where Ai is the number of times that the traveller has visited the i-th scenic spot, and 0≤A1,A2,A3,A4≤100. If Ai is zero, it means that the traveller has never been visiting the i-th spot.

Output
For each test case, output a line containing one string denoting the classification of the traveller which should be one of the strings “Typically Otaku”, “Eye-opener”, “Young Traveller”, “Excellent Traveller” and “Contemporary Xu Xiake” (without quotes).

题目大意:
每一行给出一个旅行者访问每个景点的次数,要求你输出一个表示旅行者分类的字符串。

思路:
模拟题,直接计算每个旅行者访问不同景点的个数,然后根据数量找到对应的分类输出。
代码:

#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
typedef long long ll;

int main(){
	int i,j,x,n,cnt=0;
	cin>>n;
	while(n--){
		cnt=0;
		for(j=1;j<=4;j++){
			cin>>x;
			if(x>0){
				cnt++;
			}
		}
		if(cnt==0){
			cout<<"Typically Otaku"<<endl;
		}
		else if(cnt==1){
			cout<<"Eye-opener"<<endl;
		}
		else if(cnt==2){
			cout<<"Young Traveller"<<endl;
		}
		else if(cnt==3){
			cout<<"Excellent Traveller"<<endl;
		}
		else if(cnt==4){
			cout<<"Contemporary Xu Xiake"<<endl;
		}
	}
	return 0;
}

I. The 3n + 1 problem

在这里插入图片描述在这里插入图片描述
Input
The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 10,000 and greater than 0.

You should process all pairs of integers and for each pair determine the maximum cycle length over all integers between and including i and j.

Output
For each pair of input integers i and j you should output i,j, and the maximum cycle length for integers between and including i and j. These three numbers should be separated by at least one space with all three numbers on one line and with one line of output for each line of input. The integers i and j must appear in the output in the same order in which they appeared in the input and should be followed by the maximum cycle length (on the same line).

题目大意:
输入一个整数对 i,j,对于每一对,确定所有整数(包括i和j)之间的最大周期长度。

思路:
题目很简单,照着给定公式计算输出即可,需要注意的两个地方是:
1.i 和 j 的大小不确定,所以得先判断大小,然后进行遍历。
2.输出的说明:输入原来的i和j,还有当前最长序列数,三者用一个空格隔开。
代码:

#include<iostream>
#include<math.h>
using namespace std;
typedef long long ll;

int main(){
	ll i,x,y,t,cnt,num,ans=-1;
	int flag=0;
	while(cin>>x>>y){
		if(x>y){
			flag=1;
			t=x;
			x=y;
			y=t;
		}
		ans=-1;
		for(i=x;i<=y;i++){
			num=i;
			cnt=1;
			while(num!=1){
				if(num%2==0){
					num/=2;
					cnt++;
				}
				else{
					num=num*3+1;
					cnt++;
				}
			}
			if(cnt>ans){
				ans=cnt;
			}
		}
		if(flag){
			cout<<y<<" "<<x<<" "<<ans<<endl;
		}
		else{
			cout<<x<<" "<<y<<" "<<ans<<endl;
		}
	}
	return 0;
} 

J. Above Average

It is said that 90% of frosh expect to be above average in their class. You are to provide a reality check.
Input
The first line of standard input contains an integer C, the number of test cases. C data sets follow. Each data set begins with an integer, N, the number of people in the class (1≤N≤1000). N integers follow, separated by spaces or newlines, each giving the final grade (an integer between 0 and 100) of a student in the class.
Output
For each case you are to output a line giving the percentage of students whose grade is above average, rounded to 3 decimal places.

题目大意:
给出班上学生的最终成绩(0到100之间的整数)。对于每一种情况,要求输出一行给出成绩高于平均分数的学生的百分比,四舍五入到小数点后3位。

思路:
基础题,求和相加取平均值即可。

代码:

#include<iostream>
#include<math.h>
using namespace std;
typedef long long ll;

int a[1005];
int main(){
	int i,j,t,n,cnt,sum=0;
	double ave,x;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		sum=0;
		cnt=0;
		for(i=0;i<n;i++){
			scanf("%d",&a[i]);
			sum+=a[i];
		}
		ave=(sum*1.0)/n;
		for(i=0;i<n;i++){
			if(a[i]>(int)ave){
				cnt++;
			}
		}
		x=(cnt*1.0)/n;
		printf("%.3lf%\n",x*100);
	}
	return 0;
} 

K. 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. Input is terminated by EOF.

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.

题目大意:
给你n(n>=3且n为奇数)个点的坐标,这n(按构成多边形的顺序输入的)个点必然构成一个多边形,要你按输入顺序输出这个多边形各边的中点坐标。

思路:
直接按输入顺序求出中点坐标,然后输出即可,注意最后一个中点是输入的起点和终点的中点,我用的结构体实现。

代码:

#include<iostream> 
#include<math.h>
using namespace std;
typedef long long ll;

struct node{
	double x,y;
};
 
int main(){
	int i,j,n;
	double x,y;
	node first,now,last;
	while(cin>>n)
	{
		cout<<n;
		cin>>first.x>>first.y;
		now=first;
		n--;
		while(n--){
			cin>>last.x>>last.y;
			x=(now.x+last.x)/2.0;
			y=(now.y+last.y)/2.0;
			printf(" %lf %lf",x,y);
			now=last;
		}
		x=(first.x+last.x)/2.0;
		y=(first.y+last.y)/2.0;
		printf(" %lf %lf\n",x,y);
	}
	return 0;
}

L. Specialized Four-Digit Numbers

Find and list all four-digit numbers in decimal notation that have the property that the sum of its four digits equals the sum of its digits when represented in hexadecimal (base 16) notation and also equals the sum of its digits when represented in duodecimal (base 12) notation.
For example, the number 2991 has the sum of (decimal) digits 2+9+9+1 = 21. Since 2991 = 11728 + 8144 + 9*12 + 3, its duodecimal representation is 189312, and these digits also sum up to 21. But in hexadecimal 2991 is BAF16, and 11+10+15 = 36, so 2991 should be rejected by your program.
The next number (2992), however, has digits that sum to 22 in all three representations (including BB016), so 2992 should be on the listed output. (We don’t want decimal numbers with fewer than four digits – excluding leading zeroes – so that 2992 is the first correct answer.)

Input
There is no input for this problem

Output
Your output is to be 2992 and all larger four-digit numbers that satisfy the requirements (in strictly increasing order), each on a separate line with no leading or trailing blanks, ending with a new-line character. There are to be no blank lines in the output. The first few lines of the output are shown below.

题目大意:
找到并列出所有具有这样特性的十进制的4位数字:其4位数字的和等于这个数字以16进制表示时的4位数字的和,也等于这个数字以12进制表示时的4位数字的和。

思路:
首先,设计一个函数计算和返回n转换成base进制后的各位数字之和。然后,枚举[2992…9999]内的每个数i:若Calc(10,i)== Calc(12, i)==Calc(16,i),则输出i。

代码:

#include<iostream>
#include<math.h>
using namespace std;
typedef long long ll;

int cal(int base,int n){
	int num,sum=0;
	num=n;
	while(num){
		sum+=num%base;
		num/=base;
	}
	return sum;
}
int main(){
	int i,j,ans;
	for(i=2992;i<=9999;i++){
		if(cal(10,i)==cal(12,i) &&cal(12,i)==cal(16,i)){
			cout<<i<<endl;
		}
	}
	return 0;
}

M. Pig-Latin

You have decided that PGP encryptation is not strong enough for your email. You have decided to supplement it by first converting your clear text letter into Pig Latin before encrypting it with PGP.

Input
You are to write a program that will take in an arbitrary number of lines of text and output it in Pig Latin. Each line of text will contain one or more words. A “word” is defined as a consecutive sequence of letters (upper and/or lower case). Words should be converted to Pig Latin according to the following rules (non-words should be output exactly as they appear in the input):

Words that begin with a vowel (a, e, i, o, or u, and the capital versions of these) should just have the string “ay” (not including the quotes) appended to it. For example, “apple” becomes “appleay”.
Words that begin with a consonant (any letter than is not A, a, E, e, I, i, O, o, U or u) should have the first consonant removed and appended to the end of the word, and then appending “ay” as well. For example, “hello” becomes “ellohay”.
Do not change the case of any letter.
Output
output it in Pig Latin

题目大意:
给你一种加密方式,要求你将输入的字符串转换为加密后的字符串输出。

思路:
模拟题,设计两个函数分别判断字符c是否是字母,以及是否是元音字母。在主程序中,在输入文本后,根据试题描述中给出的规则进行处理:非字母的字符,直接输出;如果是单词(一个连续的字母序列),则如果单词是辅音字母开头,则把该辅音字母放到单词的最后;然后,所有的单词后加上“ay”。

代码:

#include<iostream>
#include<string.h>
using namespace std;
typedef long long ll;

char s[1000005];
bool letter(char c){//判断是否是字母 
	if((c>='A'&&c<='Z')||(c>='a'&&c<='z')){
		return 1;
	}
	return 0; 
}
bool vowel(char c){//判断是不是元音字母 
	if(c=='A'||c=='a'||c=='E'||c=='e'||c=='I'||c=='i'||c=='O'||c=='o'||c=='U'||c=='u'){
		return 1;
	}
	return 0; 
}
int main(){
	int i,j,k;
	while(gets(s)){
		j=k=0;
		while(s[j]){
			if(letter(s[j])==0){
				cout<<s[j];
				j++;
				k=j;
			}
			else if(letter(s[k])==1){
				k++;
			}
			else{
				if(vowel(s[j])==0){
					for(i=j+1;i<k;i++){
						cout<<s[i];
					}
					cout<<s[j];
				}
				else{
					for(i=j;i<k;i++){
						cout<<s[i];
					}
				}
				cout<<"ay";
				j=k;
			}
			//cout<<endl;
		}
	}
	return 0;
}

N. Factorial! You Must be Kidding!!!

Arif has bought a super computer from Bongobazar. Bongobazar is a place in Dhaka where second hand goods are found in plenty. So the super computer bought by him is also second hand and has some bugs. One of the bugs is that the range of unsigned long integer of this computer for C/C++ compiler has changed. Now its new lower limit is 10000 and upper limit is 6227020800. Arif writes a program in C/C++ which determines the factorial of an integer. Factorial of an integer is defined recursively as:

    factorial(0)=1
    factorial(n)=n∗factorial(n−1).

Of course one can manipulate these expressions. For example, it can be written as

    factorial(n)=n∗(n−1)∗factorial(n−2)

This definition can also be converted to an iterative one.

But Arif knows that his program will not behave rightly in the super computer. You are to write program which will simulate that changed behavior in a Normal Computer.

Input
The input file contains several lines of input. Each line contains a single integer n. No integer has more than six digits. Input is terminated by end of file.

Output
For each line of input you should output a single line. This line will contain a single integer n! if the value of n! fits within the unsigned long integer of Arif’s computer. Otherwise the line will contain one of the following two words

Overflow! (When n!>6227020800)

Underflow! (When n!<10000)

题目大意:
计算n的阶乘,如果n!>6227020800,输出Overflow!,如果n!<10000,输出Underflow!,否则输出n!结果。

思路:
在这里插入图片描述

代码:

#include<iostream>
#include<math.h>
using namespace std;
typedef long long ll;
const ll x = 10000;
const ll y = 6227020800;

ll f[14];
int main()
{
	int n;
    f[0] = 1;
    for(int i=1;i<=13;i++) {
        f[i] =i*f[i-1];
    }
    while(~scanf("%d",&n))
        if(n>13||(n<0&&(n*-1)%2== 1))
            printf("Overflow!\n");
        else if(f[n]<x||(n<0&&(n*-1)%2==0))
            printf("Underflow!\n");
        else
            printf("%lld\n",f[n]);
 
    return 0;
}
 

O. Simple Addition

在这里插入图片描述

题目大意:
给出两个整数p,q的值,根据给出的式子求函数S(p,q)的值。
思路:
在这里插入图片描述

代码:

#include<iostream>
#include<math.h>
using namespace std;
typedef long long ll;

ll ans=0;
ll fac(ll n){
	if(n==0){
		return 0;
	}
	else if(n%10>0){
		return n%10;
	}
	else{
		return fac(n/10);
	}
}

void solve(ll l,ll r){ //计算S(p,q)的值 
	ll i,j;
	if(r-l<9){ //如果r-l=9,直接计算 
		for(i=l;i<=r;i++){
			ans+=fac(i);
		}
		return;
	}
	while(l%10){ //第1个区间,计算个位数的和 
		ans+=fac(l);
		l++;
	}
	while(r%10){ //第3个区间,计算个位数的和 
		ans+=fac(r);
		r--;
	}
	
	ans=ans+45*(r-l)/10; //第2个区间,计算个位数的和 
	solve(l/10,r/10);  //递归进入下一轮 
}
int main(){
	ll l,r;
	while(cin>>l>>r){
		if(l==-1 && r==-1){
			break;
		}
		ans=0;
		solve(l,r);
		cout<<ans<<endl;
	}
	return 0;
}

Q. Satellites

在这里插入图片描述
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.

题目大意:
给出人造卫星与地球表面的距离s,两颗人造卫星对地球中心的夹角a,以及一个字符串,要求你计算两个卫星之间的圆弧距离和直线弦距离。

思路:
在这里插入图片描述

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pi acos(-1)

int main(){
	double r,s,a,angle,arc,dis;
	string c;
	r=6440;
	while(cin>>s>>a>>c){
		if(c=="min"){
			a/=60;
		}
		angle=a*(pi/180);
		arc=angle*(r+s); //圆弧距离
		dis=(r+s)*sin(angle/2)*2;//直线弦距离
		if(a>180){
			arc=2*pi*(r+s)-arc;
		} 
		printf("%.6f %.6f\n",arc,dis);
	}
	return 0;
}

R. 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.

题目大意:
给出平行四边形中两条相邻边端点的坐标,要求你找出第4个点的坐标。

思路:
根据平行四边形对边平行的特点即可求出第四个端点的坐标,需要注意的是两条相邻边的端点坐标,会有两个点的坐标是重复的;因此,要判定哪两个点的坐标是重复的。

代码:

#include<iostream>
#include<math.h>
using namespace std;
typedef long long ll;

struct node{
	double x;
	double y;
};

int main(){
	node a,b,c,d,ans,temp;
	while(scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y)!=EOF){
		scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y);
		if(a.x==c.x && a.y==c.y){
			swap(a,b);
		}
		if(a.x==d.x &&a.y==d.y){
			swap(a,b);
			swap(c,d);
		}
		if(b.x==d.x &&b.y==d.y){
			swap(c,d);
		}
		ans.x=a.x+d.x-c.x;
		ans.y=a.y+d.y-c.y;
		printf("%.3lf %.3lf\n",ans.x,ans.y);
	}
	return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值