我是靠谱客的博主 受伤水壶,最近开发中收集的这篇文章主要介绍ICPC训练联盟2021寒假冬令营试题及源码答案Day 1Day 2Day 3,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ICPC训练联盟2021寒假冬令营 直播课

  • Day 1
    • A Specialized Four-Digit Numbers
    • B Pia-Latin
    • C Tic Tac Toe
    • D Factorial! You Must be Kidding!!!
    • E Function Run Fun
  • Day 2
    • A Maya Calendar
    • B Diplomatic License
    • C Accordian Patience
    • D Broken Keyboard
    • E Satellites
    • F Fourth Point!!
    • G The Circumference of the Circle
    • H Titanic
  • Day 3

Day 1

注:未添加问题描述。仅供个人学习参考。

A Specialized Four-Digit Numbers

问题描述:
(1)找到并列出所有具有这样特性的十进制的4位数字:
其4位数字的和等于这个数字以16进制表示时的4位数字的和,也等于这个数字以12进制表示时的4位数字的和。
(2)例如,整数2991的(十进制)4位数字之和是 2+9+9+1 = 21,
因为 2991 = 11728 + 8144 + 9*12 + 3,所以其12进制表示为189312,4位数字之和也是21。
但是2991的十六进制表示为BAF16,并且11+10+15 = 36,因此2991被程序排除了。
下一个数是2992,3种表示的各位数字之和都是22 (包括BB016),因此2992要被列在输出中。
(本题不考虑少于4位数字的十进制数----排除了前导零----因此2992是第一个正确答案。)
输入:
本题没有输入。
输出:
输出为2992和所有比2922大的满足需求的4位数字(以严格的递增序列),
每个数字一行,数字前后不加空格,以行结束符结束。
输出没有空行。输出的前几行如下所示。

#include <iostream>
using namespace std;
int Calc(int base,int n)	//计算和返回n转换成base进制后的各位数字之和 
{
	int sum=0;
	for(;n;n/=base)
		sum+=n%base;
	return sum;
} 
int main()
{
	int i,a;
	for(i=2992;i<9999;i++)	//枚举[2992..9999]内的每个数i 
	{
		a=Calc(10,i);
		if(a==Calc(12,i) && a==Calc(16,i))
			cout<<i<<endl;	
	} 
	return 0;
}

B Pia-Latin

问题描述:
(1)您意识到PGP加密系统还不足够保护您的电子邮件,所以,
你决定在使用PGP加密系统之前,先把您的明文字母转换成Pig Latin(一种隐语),以完善加密。
(2)每行文本将包含一个或多个单词。一个“单词”被定义为一个连续的字母序列(大写字母和/或小写字母)。
(3)单词根据以下的规则转换为Pig Latin,非单词的字符在输出时则和输入中出现的完全一样:
[1] 以元音字母(a、e、i、o或u,以及这些字母的大写形式)开头的单词,
要在其后面附加字符串“ay”(不包括双引号)。
例如,“apple”变成“appleay”。
[2] 以辅音字母(不是A, a, E, e, I, i, O, o, U 或 u的任何字母)开头的单词,
要去掉第一个辅音字母,并将之附加在单词的末尾,然后再在单词的末尾加上“ay”。
例如,“hello”变成“ellohay”。
[3] 不要改变任何字母的大小写。
输入和输出:
请您编写一个程序,输入任意数量行的文本,并以Pig Latin输出。

#include <iostream>
using namespace std;
char temp[1000005];    //输入的文本
int isab(char c)    //是否是字母
{
    if(c>='a' && c<='z')
        return 1;
    if(c>='A' && c<='Z')
        return 1;
    return 0;
}
int vowel(char c)    //是否是元音字母
{
    if(c=='a' || c=='e' || c=='i' || c=='o' || c=='u')
        return 1;
    if(c=='A' || c=='E' || c=='I' || c=='O' || c=='U')
        return 1;
    return 0;
}

int main()
{
    while(gets(temp)){
        int s=0,t=0;
        while(temp[s])
            if(!isab(temp[s])){    //不是字母
                printf("%c",temp[s++]);
                t=s;
            }
			else if(isab(temp[t]))    //是字母
                t++;
            else{
                if(!vowel(temp[s])){    //辅音字母开头
                    for(int i=s+1;i<t;++i)
                        printf("%c",temp[i]);
                    printf("%c",temp[s]);
                }
                else
                    for(int i=s;i<t;++i)
                        printf("%c",temp[i]);
                printf("ay");
                s=t;
            }
            printf("n");
    }
    return 0;
}

C Tic Tac Toe

#include <stdio.h>
char plant[4][4];
int i,j;
int win(char c)	//判断是否赢
{
	for(i=0;i<3;i++)
	{
		for(j=0;j<3 && plant[i][j]==c; j++)
			if(j==2) return 1;
		for(j=0;j<3 && plant[j][i]==c; j++)
			if(j==2) return 1;
	}	
	for(i=0;i<3 && plant[i][i]==c;i++)
		if(i==2) return 1;
	for(i=0;i<3 && plant[i][2-i]==c;i++)
		if(i==2) return 1;
	return 0;
} 
int main()
{
	int flag;
	int n,xcount,ocount;
	while(scanf("%d",&n)!=EOF)
	{
		getchar();
		while(n--)
		{
			xcount=0;
			ocount=0;
			for(i=0;i<3;i++)
				scanf("%s",plant[i]);
			flag=1;
			for(i=0;i<3;i++)
			{
				for(j=0;j<3;j++)
					if(plant[i][j]=='X')
						xcount++;
					else if(plant[i][j]=='O')
						ocount++;
			}
			if(win('X') && win('O'))
				flag=0;
				if(win('X')&& xcount==ocount)
					flag=0;
				if(ocount>xcount || xcount-ocount>1)
					flag=0;
				if(win('O') && ocount!=xcount)
					flag=0;
				if(win('X') && ocount==xcount)
					flag=0;
				if(flag)
					printf("yesn");
				else
					printf("non");
		}
	}
	return 0;
}

D Factorial! You Must be Kidding!!!

问题描述:
Arif在Bongobazar买了台超级电脑。Bongobazar是达卡(Dhaka)的二手货市场,因此他买的这台超级电脑也是二手货,存在一些问题。
其中一个问题是这台电脑的C/C++编译器的无符号长整数的范围已经被改变了。现在新的下限是10000,上限是6227020800.Arif用C/C++写了一个程序,确定一个整数的阶乘。
整数的结成递归定义为:
Factorial(0)=1;
Factorial(n)=nFactorial(n-1)
当然,可以改变这样的表达式,例如,可以写成:
Factorial(n)=n
(n-1)*Factorial(n-2)
这一定义也可以转换为迭代的形式。
但Arif知道,在这台超级电脑上,这一程序不可能正确地运行。
请您编写一个程序,模拟在正常的计算机上的改变行为。

输入和输出:
(1)输入包含若干行,每行给出一个整数n。不会有整数超过6位。输入以EOF结束。
(2)对于每一行的输入,输出一行。
如果n!的值在Arif 计算机的无符号长整数范围内,输出行给出n!的值;
否则输出行给出如下两行之一:
Overflow! //(当 n! > 6227020800)
Underflow! //(当 n! < 10000)

#include <iostream>
using namespace std;
const long long FACT1=10000,FACT2=6227020800;	//下限和上限
const int N=13;
long long F[N+1];
void init()		//离线计算F[i]=i!, 0<i<13.
{
   F[0]=1;
   for(int i=1;i<=N;i++)
   	F[i]=i*F[i-1];	
} 
int main()
{
   init();
   int n;
   while(~scanf("%d",&n))
   	if(n>N || (n<0 && (-n)%2==1))
   		printf("Overflow!n");
   	else if(F[n]<FACT1 || (n<0 && (-n)%2==0))
   		printf("Underflow!n");
   	else 
   		printf("%lldn",F[n]);
   return 0;
}

E Function Run Fun

#include <stdio.h>
#include <string.h>
#define N 20
int f[N+1][N+1][N+1];	//三维的数组f[a][b][c]用于记忆w(a,b,c) 
int w(int a,int b,int c)	//根据递归定义给出递归函数w 
{
	if(a<=0 || b<=0 || c<=0) return 1;
	else if(a>N || b>N || c>N) return w(N,N,N); 
	else if(f[a][b][c]) return f[a][b][c];	//f[a][b][c]已经记忆w(a,b,c) 
	else if(a<b && b<c) return f[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
	else return f[a][b][c]=w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1); 
}
int main(void)
{
	memset(f,0,sizeof(f));	//三维的数组f初始化赋值0 
	int a,b,c;
	while(scanf("%d%d%d",&a,&b,&c)!=EOF){	//每次循环处理一个整数三元组 
		if(a==-1 && b==-1 && c==-1) return 0;
		printf("w(%d,%d,%d)=%dn",a,b,c,w(a,b,c));
	}
	return 0;
}

Day 2

A Maya Calendar

#include <iostream>
#include <string>
using namespace std;
string haab[19]={"pop","no","zip","zotz","tzec","xul","yoxkin","mol","chen","yax","zac","ceh","mac","kankin","muan","pax","koyab","cumhu","uayet"};	//Haab历
string tzolkin[20]={"imix","ik","akbal","kan","chicchan","cimi","manik","lamat","muluk","ok","chuen","eb","ben","ix","mem","cib","caban","eznab","canac","ahau"};	//	Tzolkin历
struct data
{
	int date;
	string month;
	int year;	
};	//表示日期的结构体
void convert(data &x)	// 
{
	long current;
	int i;
	for(i=0;i<20;++i)	//当前月份是Haab历的哪个月
		if(x.month==haab[i]) break;
	current=x.year*365+i*20+x.date+1;	//这一日期从世界开始记起的天数 
	int num,year=0;	//num为输出中的数字,year为输出中的年份 
	string word;
	if(current%13==0)
		num=13;
	else
		num=current%13;
	while((current-260)>0)	//Tzolkin历一年260天 
	{
		++year;
		current-=260;
	}
	if(current==0)
		word="ahau";	//表示前一年的最后一天 
	else
	{
		while((current-20>0))
			current-=20;
		if(current==0)
			word="ahau";	//表示前一个月的最后一天 
		else
			word=tzolkin[current-1];
	}
	cout<<num<<" "<<word<<" "<<year<<endl;
} 
int main()
{
	int i,n;
	char ch;	//用于存储输入中的点'.' 
	cin>>n;
	data *p=new data[n];
	for(i=0;i<n;++i)
		cin>>p[i].date>>ch>>p[i].month>>p[i].year;	//输入Haab历日期 
	cout<<n<<endl;
	for(i=0;i<n;++i)
		convert(p[i]);
	return 0;
}

B Diplomatic License

#include <iostream>
using namespace std;
struct Point
{
	long long x,y;
}first,last,now;	//x和y坐标的结构体表示 
int n;	//n个国家 
int main()
{
	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,(now.y+last.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

#include <stdio.h>
struct Node
{
	int size;	//为牌顶时的牌的张数 
	Node *pre,*post;	//前后指针 
	Node *down;		//牌堆下一张牌的指针 
	char a,b;	//面值和花色 
	Node():pre(NULL),post(NULL),down(NULL),size(1){}
};
inline void insertNode(Node *&m,Node *&n)	//节点n替代节点m
{
	n->post=m->post;
	n->pre=m->pre;
	if(m->post) m->post->pre=n;	//如果节点m有前驱和后继 
	if(m->pre) m->pre->post=n;
}
inline void takeoutNode(Node *&n)	//节点n从牌顶取走 
{
	if(n->down) 	//如果牌堆中有下一张牌 
	{
		Node *down=n->down;	
		insertNode(n,down);
		return;
	}
	if(n->pre) n->pre->post=n->post;	//如果节点n有前驱和后继 
	if(n->post) n->post->pre=n->pre;  
}
inline void inStackNode(Node *&m,Node *&n)	//节点n放在节点m为堆顶的牌堆 
{
	n->size=m->size+1;
	insertNode(m,n);
	n->down=m;
}
inline bool checkMovable(Node *n,Node *m)	//检查节点n和节点m是否匹配 
{
	return n->a==m->a || n->b==m->b;
}
inline void pre3(Node *&n)	//左边第三张
{
	if(n->pre) n=n->pre;
	if(n->pre) n=n->pre;
	if(n->pre) n=n->pre; 
} 
inline void pre1(Node *&n)	//左边第一张 
{
	if(n->pre) n=n->pre;
}
inline void deleteNodes(Node *&n)	//删除操作,用于每个测试用例之后,释放空间 
{
	while(n)
	{
		Node *p=n->post;
		while(n)
		{
			Node *d=n->down;
			delete n; n=NULL;
			n=d;
		}
		n=p;
	}
}

int main()
{
	Node *head =new Node;	//虚拟头节点
	while(true)
	{
		Node *it =new Node;
		it->a=getchar();
		if(it->a=='#') break;
		it->b=getchar();
		getchar();
		head->post=it;		//链表初始化
		it->pre=head;
		for(int i=1;i<52;i++)	//当前测试用例,52张牌构成线性链表
		{
			Node *p=new Node;
			p->a=getchar();  
	 		p->b=getchar();
	 		getchar();
	 		it->post=p;
	 		p->pre=it;
	 		it=p;
	 	}
	 	bool checkMove=true;
	 	while(checkMove)	//移动牌规则
		{
			checkMove=false;
			it=head->post;
			while(it)
			{
				Node *post=it->post;
				Node *p=it;
				pre3(p);	//左边第三张牌是否匹配
				if(p && p!=head && checkMovable(p,it))
				{
					checkMove=true;
					takeoutNode(it);
					inStackNode(p,it);
					break;
				}
				p=it;
				pre1(p);	//左边第一张牌是否匹配
				if(p && p!=head && checkMovable(p,it)) 
				{
					checkMove=true;
					takeoutNode(it);
					inStackNode(p,it);
					break;
				}
				it=post;
			} 		//while(it)
		} 			//while(checkMove && piles>1) 
		it=head->post;
		int piles=0;
		while(it)	//游戏结束时的牌堆
		{
			piles++;
			it=it->post; 
		} 
		if(piles==1) printf("%d piles remaining:",piles);	//输出结果
		else printf("%d piles remaining:",piles);
		it=head->post;
		while(it)
		{
			printf(" %d",it->size);
			it=it->post;
		}
		putchar('n');
		deleteNodes(head->post);	//删除链表,释放空间 
	}	//while(true)
	delete head;
	return 0; 
}

D Broken Keyboard

#include <bits/stdc++.h>
using namespace std;
#define maxl 100005		//字符串最长长度
int main()
{
	char s[maxl];	//输入的字符串
	while(~scanf("%s",s+1))		//每次循环,处理一个测试用例
	{
		int Next[maxl]={0};		//链表初始化
		int cur=0,last=0;		//指针变量cur和last如试题解析所述
		for(int i=1;s[i];++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;	//last的更新
				cur=i;	//cur的更新 
			} 
		} 
		for(int i=Next[0];i!=0;i=Next[i])	//输出
			if(s[i]!='[' && s[i]!=']')
				printf("%c",s[i]);
			printf("n"); 
	} 
	return 0;
} 

E Satellites

#include <iostream>
#include <cmath>
using namespace std;
const double r=6440;	//地球半径
int main()
{
	double ss,as;	//ss:卫星与地球表面的距离;	as:两颗卫星对地球中心的夹角
	char s[10];		//保存"min"或"deg" 
	while(cin>>ss>>as>>s){
		if(s[0]=='m')
			as=as/60;	//分转换为度
		double angle = M_PI*as/180;
		double arc=angle*(ss+r);	//圆弧距离
		double dis=2*(ss+r)*sin(angle/2);	//直线弦距离
		if(as>180) arc=2*M_PI*(ss+r)-arc;	//夹角大于180度的情况
		printf("%.6f %.6fn",arc,dis); 
	} 
	return 0;
} 

F Fourth Point!!

#include <iostream>
using namespace std;
typedef struct
{
	double x,y;	
}point;		//端点坐标
int main()
{
	point a,b,c,d,e;	//a,b,c,d:相邻边的端点
	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);
		//调整,让b和c坐标相同 
		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);
		e.x = a.x+d.x-c.x; e.y = a.y+d.y-c.y;	//第4个端点的坐标
		printf("%.3lf %.3lfn",e.x,e.y);	
	} 
	return 0;
} 

G The Circumference of the Circle

#include <stdio.h>
#include <math.h>
#define PI 3.141592653589793
double length_of_side(double x1,double y1,double x2,double y2)	//求边长
{
	double side;
	side=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
	return side;
}  
double triangle_area(double side1,double side2,double side3) 	//求三角形面积:海伦公式
{
	double p=(side1+side2+side3)/2;
	double area=sqrt(p*(p-side1)*(p-side2)*(p-side3));
	return area; 
} 
double diameter(double s,double a,double b,double c)	//求直径
{
	double diam;
	diam=a*b*c/2/s;
	return diam; 
} 
int main()
{
	double x1,y1,x2,y2,x3,y3,side1,side2,side3,s,d;
	while((scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3))!=EOF)
	{
		side1=length_of_side(x1,y1,x2,y2);	//三角形三条边的边长
		side2=length_of_side(x1,y1,x3,y3);
		side3=length_of_side(x2,y2,x3,y3);
		s=triangle_area(side1,side2,side3);	//三角形面积
		d=diameter(s,side1,side2,side3);	//外接圆直径
		printf("%.2lfn",PI*d);				//外接圆周长 
	}
	return 0; 
}

H Titanic

#include <iostream>
#include <cmath>
using namespace std;
double dist(double l1,double d1,double l2,double d2)	//计算两点距离
{
	double r=6875.0/2;	//地球半径
	double p=acos(-1.0);	//PI
	l1*=p/180;  d1*=p/180;	//度转换为弧度
	l2*=p/180;  d2*=p/180;
	return r*acos(cos(l1)*cos(l2)*cos(d1-d2)+sin(l1)*sin(l2));	//距离 
}
int main()
{
	char temp[100];
	double d,m,s,l1,l2,d1,d2,dis;
	for(int i=0;i<9;++i)
		scanf("%s",temp);
	scanf("%lf^%lf'%lf" %s",&d,&m,&s,temp);	//船的位置
	l1=d+m/60+s/3600;	//转换为度
	if(temp[0]=='S')	//负方向
		l1*=-1;
		scanf("%s",temp);
		scanf("%lf^%lf'%lf" %s.",&d,&m,&s,temp);
		d1=d+m/60+s/3600;	//转换为度
		if(temp[0]=='W') d1*=-1;	//负方向
		for(int i=0;i<5;++i)
			scanf("%s",temp);
		scanf("%lf^%lf'%lf" %s",&d,&m,&s,temp);	//冰山的位置
		l2=d+m/60+s/3600;
		if(temp[0]=='S')
			l2*=-1;
		scanf("%s",temp);
		scanf("%lf^%lf'%lf" %s",&d,&m,&s,temp);
		d2=d+m/60+s/3600;
		if(temp[0]=='W')
			d2*=-1;
		scanf("%s",temp);
		dis=dist(l1,d1,l2,d2);	//船和冰山的距离
		printf("The distance to the iceberg: %.2lf miles.n",dis);
		if(floor(dis+0.005)<100)	//距离小于100英里
			printf("DANGER!n");
		return 0; 
}

Day 3

最后

以上就是受伤水壶为你收集整理的ICPC训练联盟2021寒假冬令营试题及源码答案Day 1Day 2Day 3的全部内容,希望文章能够帮你解决ICPC训练联盟2021寒假冬令营试题及源码答案Day 1Day 2Day 3所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部