Codeforces Round #288 (Div. 2) 待续

 

A. Pasha and Pixels ( 暴力 )

题意:给一个n*m的矩阵染色(初始为全白),如果在k步之内染出一个2*2的矩阵,输出最小步数,否则输出0

分析:brute force
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath>

using namespace std; int M[ 1010 ][ 1010 ]; int step, r, c, k, a, b, ans, flag; int check( int a, int b ) { if( M[a][b] && M[a][b-1] && M[a-1][b] && M[a-1][b-1] )     return 1; if( M[a][b] && M[a][b+1] && M[a-1][b] && M[a-1][b+1] )     return 1; if( M[a][b] && M[a+1][b] && M[a][b-1] && M[a+1][b-1] )     return 1; if( M[a][b] && M[a+1][b] && M[a][b+1] && M[a+1][b+1] )     return 1; else return 0; } int main() { scanf( "%d %d %d", &r, &c, &k ); step = ans = flag = 0; memset( M, 0, sizeof( M ) ); for( int i = 0; i < k; ++i ) { scanf( "%d %d", &a, &b ); M[ a ][ b ] = 1; step++; if( check( a, b ) && !flag ) { flag = 1; ans = step; } } printf( "%d\n", ans ); return 0; }
View 代码君

 

 

 

B. Anton and currency you all know ( 贪心 )

 

题意:给定一个奇数,通过交换两个digits变为偶数,且使得这个偶数最大

分析:

首先判断这个数中是否存在偶数位,如果不存在,直接输出-

从左往右扫,找到第一个偶数位,且这个偶数位 < 末尾, 交换它们

否则,从右往左找,找到第一个偶数位,交换它们。
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <cmath>

using namespace std;



char s[ 100010 ];

int x, len, sw, flag;

int main()

{

    scanf( "%s", s );

    x = len = sw = flag = 0;

    for( int i = 0; s[i]; ++i )

    {

        x = ( s[i] - '0' );

        if( ( x & 1 ) == 0 )    flag = 1;

        len++;

    }

    if( !flag ) puts( "-1" );

    else

    {

        x = s[ len - 1 ] - '0';

        for( int i = 0; i < len - 1; ++i )

        {

            if( ( ( s[i] - '0' ) & 1 ) == 0 && ( s[i] - '0' )  < x )

            {

                s[ len - 1 ] = s[i];

                s[i] = x + '0';

                sw = 1;

                break;

            }

        }

        if( sw )    puts( s );

        else

        {

            for( int i = len - 1; i >= 0; --i )

            {

                if( ( ( s[i] - '0' ) & 1 ) == 0 )

                {

                    char c = s[ len - 1 ];

                    s[ len - 1 ] = s[i];

                    s[i] = c;

                    puts( s );

                    break;

                }

            }    

        }

    }

    return 0;

}
代码君

 

 

D. Tanya and Password ( 欧拉路径 )

题意:给定n个长度为3的子串。问这n个子串能否拼接成一个长度为n+2的串。

分析:可以将题目抽象为求一个有向图的欧拉路径.

处理:因为只出现了a-z A-Z 0-9 所以给这些字符编号

字符串的前两个字符看成一个62进制的两位数,后两个字符看成一个62进制的两位数

两个子串可以连接当且仅当一个子串的后两个字符和另一个子串的前两个字符相等. 如 abc与 bcd连接后得到abcd.

建图:如果两个子串能相连,就建立一条有向边,这样构建出我们需要的图。



有向图存在欧拉路径的条件就是:

    所有顶点出度等于入度(欧拉回路)

    只有一个顶点出度比入度大一,只有一个顶点入度比出度大一,其他顶点均出度等于入度
#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;



#define maxm 3844

#define maxn 200020

#define clr( a, b ) memset( a, b, sizeof(a) )



int ind[ maxm + 10 ], outd[ maxm + 10 ];

int ans[ maxn ];

int g[ maxm + 10 ][ maxm + 10 ];

int n, ct;

char s[ 10 ];



int tran( char ch )

{

    if( ch >= 'a' && ch <= 'z' ) return ch - 'a';

    if( ch >= 'A' && ch <= 'Z' ) return ch - 'A' + 26;

    return ch - '0' + 52;

}



void read()

{

    scanf( "%d", &n );

    getchar();

    for( int i = 0; i < n ; ++i )

    {

        scanf( "%s", s );

        int u = 62 * tran( s[0] ) + tran( s[1] );

        int v = 62 * tran( s[1] ) + tran( s[2] );



        g[u][v]++;

        outd[u]++;    ind[v]++;

    }

}



void out( int x )

{

    if( 0 <= x && x <= 25 ) putchar( x + 'a' );

    else if( 26 <= x && x < 52 ) putchar( x - 26 + 'A' );

    else putchar( x - 52 + '0' );

}



int check()

{

    int sta = -1;

    for( int i = 0; i <= maxm; ++i )

    {

        if( ind[i] - outd[i] > 1 || ind[i] - outd[i] < -1 ) return -1;

        if( outd[i] > ind[i] )

        {

            if( sta != -1 )    return -1;

            sta = i;

        }

    }

    if( sta == -1 )

    {

        for( int i = 0; i <= maxm; ++i )

            if( outd[i] )    return i;

            

    }

    return sta;

}



void dfs( int u )

{

    for( int v = 0; v <= maxm; ++v )

    {

        while( g[u][v] )

        {

            g[u][v]--;

            dfs( v );

            ans[ct++] = v;

        }

    }

}



void solve()

{

    int sta = check();

    if( sta == -1 ) puts( "NO" );

    else

    {

        dfs( sta );

        ans[ ct++ ] = sta;

        if( ct != n + 1 ) puts( "NO" );

        else

        {

            puts( "YES" );

            out( ans[ ct - 1 ] / 62 );

            for( int i = ct - 1; i >= 0; --i )

                out( ans[ i ] % 62 );

            putchar( '\n' );

        }

    }

}



void init()

{

    clr( g, 0 );

    clr( outd, 0 );

    clr( ind, 0 );

    clr( s, 0 );

    clr( ans, 0 );

    ct = 0;

}



int main()

{

    init();

    read();

    solve();

    return 0;

}
代码君

 

 

 

 

你可能感兴趣的:(codeforces)