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を付けてからいろいろ変えて、コードが少しブス==間に合わせに見ましょう・・・
#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; }