国庆七天乐 Day1

国庆这几天都是做比赛,从今天的情况来说,感觉我还是弱了一点,有些该出的题没做出来,模拟题做得

比较少,该考虑的情况没有考虑,所以E题写了一半,脑子就乱了没写下去,交给了队友。有一种感觉是

学了的东西用不上,或者说不会用,还有好多东西没学。

POJ 3311

Hie with the Pie
这道题其实隽遒学弟的思路没有错,先floyd求出任意两点间的最短路,然后就是旅行商问题(哈密顿回路),
也可以说是状态压缩DP。最多一共就2的11次方乘以10种状态,用f[i][j]表示第i种状态处于j点的最小代价,
我们要求的就是f[(1 <<(n + 1) - 1)[0],从零点出发回到零点。
#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <algorithm>

using namespace std;



const int MAXN = 15;

int d[MAXN][MAXN], f[1 << MAXN][MAXN];

int n;



void ReadGraph()

{

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

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

        {

            scanf("%d", &d[i][j]);

        }

}



void floyd()

{

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

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

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

            {

                if(d[i][j] > d[i][k] + d[k][j])

                    d[i][j] = d[i][k] + d[k][j];

            }

}



void dp()

{

    int i, j, k;

    memset(f, -1, sizeof f);

    f[1][0] = 0;

    for(i = 1; i <= (1 << (n + 1)); i ++)

    {

        i = i | 1;

        for(j = 0; j <= n; j ++)

        {

            if(f[i][j] != -1)

            {

                for(k = 0; k <= n; k ++)

                {

                    if(k != j && (f[(1 << k) | i][k] == -1 || f[(1 << k) | i][k] > f[i][j] + d[j][k]))

                        f[ (1 << k) | i][k] = f[i][j] + d[j][k];

                }

            }

        }

    }

    printf("%d\n", f[(1 << (n + 1)) - 1][0]);

}



int main()

{

    while(scanf("%d", &n), n)

    {

        ReadGraph();

        floyd();

        dp();

    }

    return 0;

}

 POJ 3316

Snakes on a Plane
这道题当时没看明白,比赛后才理解了题意,我的理解是求出格子中不能变长的贪食蛇的个数。
#include <stdio.h>

#include <string.h>

#include <stdlib.h>



const int MAXN = 205;

const int dx[] = {1, -1, 0, 0};

const int dy[] = {0, 0, 1, -1};

char g[MAXN][MAXN];

int r, c;



void ReadGraph()

{

    char str[MAXN];

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

    {

        scanf("%s", str);

        for(int j = 0; j < c; j ++)

        {

            g[i][j] = str[j];

        }

    }

}



void mark(int a, int b)

{

    g[a][b] = '2';

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

    {

        int nx = a + dx[i], ny = b + dy[i];

        if(nx >= 0 && nx < r && ny >= 0 && ny < c && g[nx][ny] == '1')

        {

            mark(nx, ny);

        }

    }

}



int count(int a, int b)

{

    int cnt = 0;

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

    {

        int nx = a + dx[i], ny = b + dy[i];

        if(nx >= 0 && nx < r && ny >= 0 && ny < c && g[nx][ny] != '0')

        {

            cnt ++;

        }

    }

    return cnt;

}



bool IfExtend(int a, int b)

{

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

    {

        int nx = a + dx[i], ny = b + dy[i];

        if(nx >= 0 && nx < r && ny >= 0 && ny < c && g[nx][ny] == '0')

        {

            if(count(nx, ny) == 1) return false;

        }

    }

    return true;

}



bool IsAnEnd(int a, int b){

    if((count(a, b) == 0 || count(a, b) == 1)){

        if(IfExtend(a, b)){

            return true;

        }

        else{

            mark(a, b);

            return false;

        }

    }

    else

        return false;

}



bool check(int a, int b){

    int neighbors = count(a, b);

    if(neighbors == 1 || neighbors == 0) {

        g[a][b] = '2';

        return IfExtend(a, b);

    }

    if( neighbors > 2) {

        mark(a, b);

        return false;

    }

    g[a][b] = '2';

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

    {

        int nx = a + dx[i], ny = b + dy[i];

        if(nx >= 0 && nx < r && ny >= 0 && ny < c && g[nx][ny] == '1')

        {

            return check(nx, ny);

        }

    }

}





bool startSnake(int a, int b){

    int neighbors = count(a, b);

    if(count(a, b) == 0) return true;

    g[a][b] = '3';

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

    {

        int nx = a + dx[i], ny = b + dy[i];

        if(nx >= 0 && nx < r && ny >= 0 && ny < c && g[nx][ny] == '1')

        {

            return check(nx, ny);

        }

    }

}



int calc(){

    int noSnakes = 0;

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

        for(int j = 0; j < c; j ++){

            if(g[i][j] == '1'){

                if(IsAnEnd(i, j)){

                    if(startSnake(i, j)){

                        noSnakes++;

                    }

                    mark(i,j);

                }

            }

    }

    return noSnakes;

}



int main()

{

    while(scanf("%d%d", &r, &c), r + c)

    {

        ReadGraph();

        printf("%d\n", calc());

    }

    return 0;

}

 

你可能感兴趣的:(a)