列表

详情


NC15478. 白金元首与七彩魔法

描述

于是这天元首不明所以地被地外生物Kyubey忽悠去成为了魔法元首。不过在开始练习魔法之前,元首需要为自己的魔法选择一个代表色。
下图是一个明度最大(即,HSV色彩空间中V=100%)的单位圆色盘。色盘上任意一点的坐标为一个非负实数对(α°,r%)(0≤α<360,0≤r≤100),表示色相为α°、饱和度为r%的颜色。另一种理解是,α°表示从联结圆心和纯红色点的射线顺时针到达该点所经过的角度,r/100是该点到单位圆圆心的距离。

具体而言,从这个坐标(α°,r%)到红绿蓝颜色值(R,G,B)的转换如下

请参照样例确认你对公式的理解和实现。
按照Kyubey的判断,元首可以选择色盘所在的平面上一条给定直线段1°,r1%)–(α2°,r2%)上的任意颜色。元首可不需要犹豫,作为一名blingbling的帝国领导者,当然要选择最亮的颜色啦!
一个颜色(R,G,B)的亮度定义为L=0.30R+0.59G+0.11B。下图给出了彩色色盘和表示亮度的灰度色盘的左右对比。
你需要编写程序帮助元首计算给定直线段上所有颜色的最大亮度。

输入描述

输入的第一行包含一个正整数 T —— 数据的组数。接下来包含 T 组数据,格式如下,数据间没有空行。
 第 1 行:四个空格分隔的整数 α1、r1、α2、r2

输出描述

对于每组数据输出一行,包含一个 [0, 1] 范围内的十进制小数 —— 直线段(α1°,r1%)–(α2°,r2%)上所有颜色的最大亮度,四舍五入保留恰好四位小数。数据保证若参考答案为 A,则 [A - 10-5, A + 10-5] 范围内任意实数四舍五入到第四位小数后均相等。

示例1

输入:

6
30 30 30 30
120 60 120 60
270 100 270 100
30 30 120 60
120 60 270 100
270 100 30 30

输出:

0.8785
0.7540
0.2600
0.9704
0.9408
0.8785

说明:

点(30°,30%)的红绿蓝颜色值为(1.00,0.85,0.70),亮度为0.301.00+0.590.85+0.110.70=0.8785;
点(120°,60%)的红绿蓝颜色值为(0.40,1.00,0.40),亮度为0.300.40+0.591.00+0.110.40=0.7540;
点(270°,100%)的红绿蓝颜色值为(0.50,0.00,1.00),亮度为0.300.50+0.590.00+0.111.00=0.2600。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 2247ms, 内存消耗: 492K, 提交时间: 2020-03-10 19:22:21

#include<cmath>
#include<cstdio>
#include<algorithm>
inline double luminance(double x,double y)
{
	double a=atan2(y,x);
	double d=sqrt(x*x+y*y);
	double r,g,b;
	if(a<0) a+=M_PI*2;
	if(a<M_PI*1/3)
	{
		r=1;
		g=a/(M_PI*1/3);
		b=0;
	}
	else if(a<M_PI*2/3)
	{
		r=2-a/(M_PI*1/3);
		g=1;
		b=0;
	}
	else if(a<M_PI*3/3)
	{
		r=0;
		g=1;
		b=a/(M_PI*1/3)-2;
	}
	else if(a<M_PI*4/3)
	{
		r=0;
		g=4-a/(M_PI*1/3);
		b=1;
	}
	else if(a<M_PI*5/3)
	{
		r=a/(M_PI*1/3)-4;
		g=0;
		b=1;
	}
	else
	{
		r=1;
		g=0;
		b=6-a/(M_PI*1/3);
	}
	r=(1-d)+d*r;
	g=(1-d)+d*g;
	b=(1-d)+d*b;
	return r*0.30+g*0.59+b*0.11;
}
int main()
{
	int T;
	scanf("%d",&T);
	int a1,r1,a2,r2;
	while(T--)
	{
		scanf("%d%d%d%d",&a1,&r1,&a2,&r2);
		double x1,x2,y1,y2;
		x1=cos(M_PI/180.0*a1)*r1/100;
		y1=sin(M_PI/180.0*a1)*r1/100;
		x2=cos(M_PI/180.0*a2)*r2/100;
		y2=sin(M_PI/180.0*a2)*r2/100;
		double ans=0;
		for(double z=0;z<=1;z+=1.0/131072)
		{
			double x=x1*z+x2*(1-z);
			double y=y1*z+y2*(1-z);
			ans=std::max(ans,luminance(x,y));
		}
		printf("%.4lf\n",ans);
	}
	return 0;
}

上一题