2013 ACM/ICCC Asia Regional Changsha Online–C問題Color Representation Conversion(坑父シミュレーション問題)
31637 ワード
标题:RGB、HSV、HSLの3色表示モードを与え、任意のモード間の2つの変換を実現します.
1.テーマの中で与えられた転化公式の説明を見ないほうがいいです.私は叙述の少しもはっきりしないと思います.ウィキペディアを見て、ウィキペディアの公式を一言一言翻訳すればいいと思います.
2.数式換算では、すべて小数に変換します.例えば、RGBの取値範囲0-255は、r=R/255.0、g=G/255.0 b=B/255.0に変換される…
3.HSL->RGBとHSV->RGBは四捨五入する必要があり、HSVとHSLの間の相互変換はRGB:HSV<=>RGB<=>HSLを通過する必要があり、ここでRGBを回すときは四捨五入する必要はない.
4.自分で自分を回す場合、例えばRGBB->RGBはそのまま出力します.
書くときは頭がよくわからないし、WAを付けてからいろいろ変えて、コードが少しブス==間に合わせに見ましょう・・・
1.テーマの中で与えられた転化公式の説明を見ないほうがいいです.私は叙述の少しもはっきりしないと思います.ウィキペディアを見て、ウィキペディアの公式を一言一言翻訳すればいいと思います.
2.数式換算では、すべて小数に変換します.例えば、RGBの取値範囲0-255は、r=R/255.0、g=G/255.0 b=B/255.0に変換される…
3.HSL->RGBとHSV->RGBは四捨五入する必要があり、HSVとHSLの間の相互変換はRGB:HSV<=>RGB<=>HSLを通過する必要があり、ここでRGBを回すときは四捨五入する必要はない.
4.自分で自分を回す場合、例えばRGBB->RGBはそのまま出力します.
書くときは頭がよくわからないし、WAを付けてからいろいろ変えて、コードが少しブス==間に合わせに見ましょう・・・
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const double eps = 1e-9;
struct node
{
int val[3];
bool second;
double ang[3];
};
char tar[8];
char ori[8];
node A, ans;
int dcmp( double a )
{
if ( fabs(a) < eps ) return 0;
return a < 0 ? -1 : 1;
}
int Round( double a )
{
return (int)(a + 0.5);
}
void init()
{
scanf( "%s", ori );
//printf("A: ");
char tmp[20];
for ( int i = 0; i < 3; ++i )
{
scanf( "%s", tmp );
sscanf( tmp, "%d", &A.val[i] );
//printf( "%d ", A.val[i] );
}
A.second = false;
//puts("");
return;
}
void RGBtoHSL()
{
double r, g, b;
if ( A.second )
{
r = A.ang[0];
g = A.ang[1];
b = A.ang[2];
}
else
{
r = A.val[0]/255.0;
g = A.val[1]/255.0;
b = A.val[2]/255.0;
}
double h, l, s;
//printf( "rgb: %f %f %f
", r, g, b );
double maxi = max( max(r, g), b );
double mini = min( min(r, g), b );
double delta = maxi - mini;
if ( dcmp( maxi - mini ) == 0 )
{
h = 0.0;
}
else if ( dcmp( maxi - r ) == 0 )
{
if ( dcmp( g - b ) >= 0 )
{
h = 60.0*(g-b)/delta+0;
}
else
{
h = 60.0*(g-b)/delta+360;
}
}
else if ( dcmp( maxi - g ) == 0 )
{
h = 60.0*(b-r)/delta+120;
}
else if ( dcmp( maxi - b ) == 0 )
{
h = 60.0*(r-g)/delta+240;
}
l = 0.5*(maxi+mini);
//printf("l:%f
", l);
if ( dcmp(l) == 0 || dcmp( delta ) == 0 )
{
s = 0.0;
}
else if ( dcmp(l) > 0 && dcmp( 0.5 - l ) >= 0 )
{
s = delta/(maxi+mini);
}
else
{
s = delta/(2.0-(maxi+mini));
}
//printf( "%s ", tar );
//printf("%.0f %.0f%% %.0f%%
", h+eps, s*100+eps, l*100+eps );
//printf("%d %d%% %d%%
", Round(h+eps), Round(s*100+eps), Round(l*100+eps) );
ans.val[0] = Round(h);
ans.val[1] = Round(s*100);
ans.val[2] = Round(l*100);
return;
}
void RGBtoHSV()
{
double r, g, b;
if ( A.second )
{
r = A.ang[0];
g = A.ang[1];
b = A.ang[2];
}
else
{
r = A.val[0]/255.0;
g = A.val[1]/255.0;
b = A.val[2]/255.0;
}
double h, v, s;
double maxi = max( max(r, g), b );
double mini = min( min(r, g), b );
double delta = maxi - mini;
if ( dcmp( delta ) == 0 )
{
h = 0;
}
else if ( dcmp( maxi - r ) == 0 )
{
if ( dcmp( g - b ) >= 0 )
{
h = 60.0*(g-b)/delta+0;
}
else
{
h = 60.0*(g-b)/delta+360;
}
}
else if ( dcmp( maxi - g ) == 0 )
{
h = 60.0*(b-r)/delta+120;
}
else if ( dcmp( maxi - b ) == 0 )
{
h = 60.0*(r-g)/delta+240;
}
if ( dcmp( maxi ) == 0 )
{
s = 0;
}
else s = (double)(maxi-mini)/maxi;
v = maxi;
//printf( "%s ", tar );
//printf("%f %f %f
", h+eps, s*100+eps, v*100+eps );
//printf("%d %d%% %d%%
", Round(h+eps), Round(s*100+eps), Round(v*100+eps) );
ans.val[0] = Round(h);
ans.val[1] = Round(s*100);
ans.val[2] = Round(v*100);
return;
}
void jiuzheng( double &tC )
{
if ( dcmp( tC ) < 0 ) tC += 1.0;
if ( dcmp( tC - 1.0 ) > 0 ) tC -= 1.0;
return;
}
double GetRGB( double p, double q, double tC )
{
if ( dcmp( 1.0/6.0 - tC ) > 0 )
{
return p + ( (q - p) * 6.0 * tC );
}
else if ( dcmp( 0.5 - tC ) > 0 )
{
return q;
}
else if ( dcmp( 2.0/3.0 - tC ) > 0 )
{
return p + ( (q-p)*4.0 - (q-p)*6.0*tC );
}
else return p;
}
void HSLtoRGB()
{
double h, s, l;
double r, g, b;
//int R, G, B;
h = A.val[0]/360.0;
s = A.val[1]/100.0;
l = A.val[2]/100.0;
if ( dcmp(s) == 0 )
{
r = l;
g = l;
b = l;
}
else
{
double p, q, tR, tG, tB;
if ( dcmp( 0.5 - l ) > 0 )
q = l * ( 1.0 + s );
else q = l + s - ( l * s );
p = 2 * l - q;
tR = h + 1.0/3.0;
tG = h;
tB = h - 1.0/3.0;
jiuzheng( tR );
jiuzheng( tG );
jiuzheng( tB );
//r = GetRGB( p, q, tR )*255.0;
r = GetRGB( p, q, tR );
//g = GetRGB( p, q, tG )*255.0;
g = GetRGB( p, q, tG );
//b = GetRGB( p, q, tB )*255.0;
b = GetRGB( p, q, tB );
}
//printf( "%s ", tar );
//printf( "RGB: %d %d %d
", r, g, b );
A.ang[0] = r;
A.ang[1] = g;
A.ang[2] = b;
A.val[0] = Round( r * 255 );
A.val[1] = Round( g * 255 );
A.val[2] = Round( b * 255 );
//printf("HSLtoRGB: %d %d %d
", A.val[0], A.val[1], A.val[2] );
for ( int i = 0; i < 3; ++i )
ans.val[i] = A.val[i];
return;
}
void HSVtoRGB()
{
double h, s, v;
int R, G, B;
double r, g, b;
h = A.val[0];
s = A.val[1] / 100.0;
v = A.val[2] / 100.0;
if ( dcmp(s) == 0 )
{
r = g = b = v;
}
else
{
int hi = (int)floor(h/60);
double f = h / 60 - hi;
double p = v * ( 1 - s );
double q = v * ( 1 - f*s );
double t = v * ( 1 - (1-f)*s );
switch( hi )
{
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
}
R = Round( r * 255.0 );
G = Round( g * 255.0 );
B = Round( b * 255.0 );
//printf( "%s ", tar );
//printf( "%d %d %d
", R, G, B );
A.ang[0] = r;
A.ang[1] = g;
A.ang[2] = b;
A.val[0] = R;
A.val[1] = G;
A.val[2] = B;
for ( int i = 0; i < 3; ++i )
ans.val[i] = A.val[i];
return;
}
void HSVtoHSL()
{
HSVtoRGB();
A.second = true;
RGBtoHSL();
return;
}
void HSLtoHSV()
{
HSLtoRGB();
A.second = true;
RGBtoHSV();
return;
}
int main()
{
while ( scanf( "%s", tar ) == 1 )
{
init();
if ( ori[0] == 'R' )
{
if ( tar[2] == 'L' ) RGBtoHSL();
else if ( tar[0] == 'R' )
{
for ( int i = 0; i < 3; ++i )
ans.val[i] = A.val[i];
}
else RGBtoHSV();
}
else if ( ori[2] == 'L' )
{
if ( tar[0] == 'R' ) HSLtoRGB();
else if ( tar[2] == 'L' )
{
for ( int i = 0; i < 3; ++i )
ans.val[i] = A.val[i];
}
else HSLtoHSV();
}
else
{
if ( tar[0] == 'R' ) HSVtoRGB();
else if ( tar[2] == 'V' )
{
for ( int i = 0; i < 3; ++i )
ans.val[i] = A.val[i];
}
else HSVtoHSL();
}
printf( "%s ", tar );
if ( tar[0] == 'R' )
{
printf( "%d %d %d
", ans.val[0], ans.val[1], ans.val[2] );
}
else printf( "%d %d%% %d%%
", ans.val[0], ans.val[1], ans.val[2] );
}
return 0;
}