zoukankan      html  css  js  c++  java
  • 2013 ACM/ICPC Asia Regional Changsha Online – C题 Color Representation Conversion (坑爹模拟题)

    题意:给你三种颜色表示模式,RGB,HSV和HSL,实现任意模式之间两两转化。

    1.最好别看题目中给的转化公式描述,我觉得叙述的一点也不清楚,看维基百科,把维基百科上的公式一句一句翻译过来就好

    2.在公式换算的时候,全部转成小数形式。例如:RGB的取值范围0-255转化成0-1, 即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.对于自己转自己的情况,例如RGB->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;
    }
  • 相关阅读:
    【请教】在vim中如何快速选中一个单词?并且让文本中的所有这个
    SQL中为了加强分类表的记录有效性,把主键和外键设计在了同一张表内
    JS不忘本之switch篇~建立一个菜单,并为菜单的参数来设置它的具体操作
    JS不忘本之JS类篇~类,方法,属性,子类,扩展方法在JS里的实现
    移入页面上空文本框时,让它变为焦点,移出清除焦点
    EF中数据优先,模型优先和代码优先
    关于ApplicationContext的初始化
    Linux下无线路由器的软件开发
    as3实现的拼图游戏
    AppWidgets
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3335707.html
Copyright © 2011-2022 走看看