周测一(补题)题解

题目1:

题目描述

给定 4 根木棍的长度,如果它们中存在 3 根木棍可以组成三角形,输出 TRIANGLE ;如果它们无法组成三角形,但是它们中存在 3 根木棍可以组成退化的三角形(任意两边之和大于等于第三边,但是不是三角形),输出 SEGMENT ;否则,输出 IMPOSSIBLE 。

注意: 木棍不能折断,也不能只用一部分长度。

输入格式

一行 4 个整数,4 根木棍的长度。

输出格式

如果它们中存在 3 根木棍可以组成三角形,输出 TRIANGLE ;如果它们无法组成三角形,但是它们中存在3根木棍可以组成退化的三角形,输出 SEGMENT ;否则,输出 IMPOSSIBLE

By @PC_DOS

输入输出样例

输入 #1复制

4 2 1 3

输出 #1复制

TRIANGLE

输入 #2复制

7 2 2 4

输出 #2复制

SEGMENT

输入 #3复制

3 5 9 1

输出 #3复制

IMPOSSIBLE

题解:先给四个木棍排序,只要判断一下最长的或者最短的两个木棍至少有一个可以是能与之间长度的两个木棍组成三角形,如果不能组成三角形就判断一下能不能成为退化的三角形。

代码如下

#include"stdio.h"
#include"stdlib.h"
int x[4];
int com(const void *a,const void *b)
{
	return *(int *)a-*(int *)b;
}
int dfs(int a,int b,int c)
{
	if(x[c]-x[a]<x[b]&&x[c]-x[b]<x[a]&&x[a]+x[b]>x[c])
	return 1;
	if(x[a]+x[b]>=x[c])
	return 0;
	else return -1;
}
int main()
{
	int m,i,j;
	for(m=0;m<4;m++)
	scanf("%d",&x[m]);
	qsort(x,4,sizeof(int),com);
	dfs(0,1,2);
	dfs(1,2,3);
	if(dfs(0,1,2)==1||dfs(1,2,3)==1)
	printf("TRIANGLE");
	else if(dfs(0,1,2)==-1&&dfs(1,2,3)==-1)
	printf("IMPOSSIBLE");
	else
	printf("SEGMENT");
	return 0;
 } 

题目2:

题意翻译

小Y,小W和小D进行扔骰子(六面)游戏,谁投出的点数最大算谁胜利,现在已知小Y和小W的得分,请你帮小D求出她获胜的概率

注意:

1.以"分子/分母"输出,特别的,若不可能获胜输出"0/1",100%获胜输出"1/1"

2.小Y和小W非常绅士,如果小D的得分和他们一样,他们也会算作小D获胜 Translated by @稀神探女

输入输出样例

输入 #1复制

4 2

输出 #1复制

1/2

说明/提示

Dot将去特兰西瓦尼亚,如果她幸运地滚4,5或6分。

题解:找到两个数中的最大值,判断超过最大值的结果

代码如下

#include"stdio.h"
int max(int a,int b)
{
	if(a>b)
	return a;
	return b;
}
int main()
{
	int a,b,n,m=0;
	scanf("%d%d",&a,&b);
	a=max(a,b);
	for(n=6;n>=1;n--)
	{
	if(n>=a)
	m++;
	}
	if(m==6)
	printf("1/1");
    else if(m==1)
	printf("1/6");
	else if(m%2==0)//2,4的情况
	printf("%d/%d",m/2,3);
	else if(m==3)
	printf("1/2");
	else if(m==0)
	printf("0/1");
	else if(m==5)
	printf("5/6");
	return 0;
}

题目3:

题目描述(舍弃各种乱七八糟的故事)

给定一个数N,要求把N的各个数位打乱,要求组成一个可能的,最小的数(最小数有可能含有前导0)。现在已经有一个“最小数”,请你判断这个“最小数”是不是最小数。

第一行输入n不含前导0。
第二行输入的假定的最小数可能含有前导0。 题目要求排序后的最小数不含前导0。

输入格式

两行。 第一行是给定的数N。 第二行是假定的N重组的“最小数”。

输出格式

一行。 如果输入的最小数就是N重组的最小数,输出“OK”。 否则输出“WRONG_ANSWER”。

Translated by LiM_817

输入输出样例

输入 #1复制

3310
1033

输出 #1复制

OK

输入 #2复制

4
5

输出 #2复制

WRONG_ANSWER

题解:这个题目是一个考查字符串的题目,不能用数组做!!

1.读取字符串后将字符串数组转换成整型数组(a[],b[]),首先判断一下两个字符串长度是否一样。不同就输出"WRONG_ANSWER",相同的话,然后给第一个字符串转换成的整型数组后排序,找到第一个不是0的数组元素,将这个数组元素与a[0]换值。

2.判断a数组s是否与b[]数组相等。

3.当字符串长度为1的时候,不要换值这个操作。

代码如下

#include"stdio.h"
#include"string.h"
#include"stdlib.h"
int com(const void *a,const void *b)
{
	return *(int *)a-*(int *)b;
}
int main()
{
	char s[10],s1[10];
	gets(s);
	gets(s1);
	if(strlen(s)!=strlen(s1))
	printf("WRONG_ANSWER");
	else if(strlen(s)==strlen(s1))
	{
	int i,a[10],b[10],t,sign=0;
	for(i=0;i<strlen(s);i++)
	{
		a[i]=s[i]-'0';
	}
	for(i=0;i<strlen(s);i++)
	{
		b[i]=s1[i]-'0';
	}
	qsort(a,strlen(s),sizeof(int),com);
	if(strlen(s)>1)
	{
	t=0;
	while(a[t]==0)
	t++;
	i=a[t];
	a[t]=a[0];
	a[0]=i;
	}
	for(i=0;i<strlen(s);i++)
	{
		if(a[i]!=b[i])
		{
			sign=1;
			printf("WRONG_ANSWER");
			break;
		}
	 } 
	if(sign!=1)
	printf("OK");
	}
	return 0;
}

题目4:

题意翻译

题目描述:在一坐标轴上给出n块板子,每个板子所占的空间为[(k-1)m,(k-1)m+l](l<m),一个青蛙从原点0起跳,每次跳d距离远,问最后青蛙会落在哪里(没落在板子上就结束跳跃) 输入:一行四个整数n,d,m,l 输出:一个整数,即青蛙最后的落点 1<=n,d,m,l<=10^6 l<m

Translated by 稀神探女

输入输出样例

输入 #1复制

2 2 5 3

输出 #1复制

4

输入 #2复制

5 4 11 8

输出 #2复制

20

题解:这个题目是求第一次没有跳在板子上面的位置,这个题解的精华i=(((t-1)*m+l)/d)*d+d;

我一开始用的i+=d,时间超限。为什么是i=(((t-1)*m+l)/d)*d+d?跳到这个板子上能跳的最长处再加一个d,跳出板子,t++,判断是否跳到下一个板子上。

代码如下

#include"stdio.h"
int main()
{
	long long int n,d,m,l,t,i=0,sign=0;
	scanf("%lld%lld%lld%lld",&n,&d,&m,&l);//板子长度是l。 
	for(t=1;t<=n;t++)
	{
		if((t-1)*m>i)
		break;
		while((t-1)*m+l>=i)
		i=(((t-1)*m+l)/d)*d+d;
	}
	printf("%lld",i);
	return 0;
}

题目5:

题意描述

关于 Codeforces 的网站 king Copa 经常被报道,使得它在要使用网站进行训练和比赛的人之间迅速流行开来。最近, Copa 明白,要征服世界,他需要组织世界 Codeforces 锦标赛。他希望在这次比赛之后之后,最聪明的人将成为被挑选出来成为他的下属,然后征服世界最艰难的部分将会完成。

Codeforces 世界总决赛的最后一轮定于YY 年 MM 月 DD 日举行,其中 DD 是当天的日期, MM 是当月的月份, YY 是当年的年份的最后两位。Bob 很幸运地能成为来自 Berland 的一名决赛选手。但有一个问题:根据比赛规则,所有参赛者在决赛时必须年满 18 岁。 Bob 出生于 BY 年, BM 月,BD 日。这个日期记录在他的护照上,他的护照复印件已经寄给了组织者。但是 Bob 了解到,在不同的国家,日期的书写方式是不同的。例如,在美国,先写月份,然后写日期,最后写年份。

鲍勃想知道是否有可能重新排列他出生日期的数字,以便他在 YY 年, MM 月, DD 日那天至少 18 岁。他看出,在他的祖国,日期写的顺序不一样。请帮帮他。 根据另一个奇怪的规则,合格的参赛者必须与决赛日期出生在同一个世纪。如果决赛当天刚好是参赛者的 18 岁生日,则他可以参加。

因为我们只考虑从 2001 年到 2099 年的决赛年份,所以使用以下规则:如果年份的数字可以被 4 整除,那么年份就是闰年。

输入格式:

第一行包括三个数字 DD,MM,YY ,第二行包括三个数字 BD,BM,BY ,数据保证两个日期的正确性,并且 BY 和 YY 保证在 [01,99] 中。

输出格式:

如果可能通过重新排列出生日期的顺序,让 Bob 在比赛当天至少 18 岁,则输出 YES 。如果不能,则输出 NO。

输入输出样例

输入 #1复制

01.01.98
01.01.80

输出 #1复制

YES

输入 #2复制

20.10.20
10.02.30

输出 #2复制

NO

输入 #3复制

28.02.74
28.02.64

输出 #3复制

NO

题解:

1.设置两个月份数组,一个是闰年的,其他的那一个不是闰年的。

2.输入时举办时间输入是按日月年的顺序输入的,出生日期的顺序不确定,我们要把所有情况都考虑到。

3.达到18岁或者等于18岁的条件,出生年份+18<举办年份,或者出生年份+18=举办年份,出生月份<举办月份,或者出生年份+18=举办年份,出生月份=举办月份,出生日<=举办日。

4.考虑是否是闰年。

代码如下:

#include"stdio.h"
int r[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//每个月的天数
int r1[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int t[3];
int ss(int a,int b,int c)//日月年 
{
	if(c%4!=0&&c>0)
	{
	if(b<=12&&b>=1&&a<=r[b])
	{
		if((c+18<t[2])||(t[2]==c+18&&t[1]>b)||(t[2]==c+18&&t[1]==b&&t[0]>=a))
		return 1;
		else return 0;
	} 
	else return 0;
	}
	if(c%4==0&&c>0)
	{
	if(b<=12&&c>=1&&b>=1&&a<=r1[b])
	{
		if((c+18<t[2])||(t[2]==c+18&&t[1]>b)||(t[2]==c+18&&t[1]==b&&t[0]>=a))
		return 1;
		else return 0;
	} 
	else return 0;	
	}
	if(c==0)
	return 0;
} 
int main()
{
	int a,b,c;
	scanf("%d.%d.%d",&t[0],&t[1],&t[2]);//举办日月年固定的 
	scanf("%d.%d.%d",&a,&b,&c);//出生不固定
	if(ss(a,b,c)||ss(a,c,b)||ss(b,a,c)||ss(b,c,a)||ss(c,b,a)||ss(c,a,b))
	printf("YES");
	else printf("NO");
	return 0;
 } 

题目6:

题意翻译

  • 给出一个序列 a,求出一个长度不超过 3n 的操作序列,使序列 a 中每个元素相等。

  • 定义一次操作为:选出 (i,j,x) 三元组,满足i,j 为序列合法下标,x 为 10^9 以内非负整数,令 ai​:=ai​−x⋅i,aj​:=aj​+x⋅i。

  • 必须保证操作过程中的任意时刻序列 a 中每个元素都非负。

  • 输出时先输出操作次数 k,然后输出 k 行操作序列。

  • 数据组数 t≤10^4,序列长度n≤10^4,元素大小 1≤ai​≤10^5。

输入输出样例

输入 #1复制

3
4
2 16 4 18
6
1 2 3 4 5 6
5
11 19 1 1 3

输出 #1复制

2
4 1 2
2 3 3
-1
4
1 2 4
2 4 5
2 3 3
4 5 1

题解:

1.a[i​]:=a[i]​−x⋅i,a[j]​:=a[j]​+x⋅i,a[i]+a[j]的值是不变的,所以不论怎么操作数组的和sum是不变的,题目的题意就是让所有值都等于平均值,那么sum%n!=0

2.我们可以用a[1]做文章,因为无论怎么样每个数都可以把1整除,我的想法是把所有值都移到a[1],然后再把数从a[1]平分给每一个数。(n-1步)

3.怎么把其他的数移到a[1](最多要两步),有两种情况,一种是a[i]%i==0,这种自己移;一种是a[i]%i!=0,这种情况要先向a[i]借a[i]/i+1)*i-a[i],然后再移。

4.所以这样走最坏的情况也只有3*(n-1)步。

5.用一个数来记录要走多少步,然后用一个结构体将走的步中的数据存储下来,最后遍历输出。 

代码如下:

#include"stdio.h"
#include"string.h"
struct node
{
	int i;
	int y;
	int x;
}d[30001];
int main()
{
	int n,m,t,a[10009],i;
	scanf("%d",&n);
	for(m=0;m<n;m++)
	{
		int sum=0,p=0;
		memset(d,0,sizeof(struct node));
		scanf("%d",&t);//长度不超过3t的操作序列
		for(i=1;i<=t;i++)
		{
		scanf("%d",&a[i]);
		sum+=a[i];
		}
		if(sum%t!=0)
		printf("-1\n");
		else
		{
			for(i=2;i<=t;i++)
			{
				if(a[i]%i!=0)
				{
				d[p].i=1,d[p].y=i,d[p].x=(a[i]/i+1)*i-a[i];
				a[1]-=(a[i]/i+1)*i-a[i];
				a[i]+=(a[i]/i+1)*i-a[i];
				p++;
				}
				if(a[i]%i==0)
				{
				d[p].i=i,d[p].y=1,d[p].x=a[i]/i;
				a[1]+=a[i];
				a[i]=0;
				p++;
				}
			}
			for(i=2;i<=t;i++)
			{
			d[p].i=1;d[p].y=i,d[p].x=sum/t;
			a[1]-=sum/t;
			a[i]+=sum/t;
			p++;
			}
			printf("%d\n",p);
			for(i=0;i<p;i++)
			printf("%d %d %d\n",d[i].i,d[i].y,d[i].x);
		}
	}
	return 0;
 } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值