回 帖 发 新 帖 刷新版面

主题:第74次比赛结果


第一题:
测试分为10个实例,n分别为2,10,100,1000,10000,100000,500000,1000000,5000000,10000000,序列数据为随机生成,下面是测试结果:
2楼 fenix124        220ms
4楼 flushtime       290ms
5楼 strugglemyself  结果错误 
7楼 debroa723       3020ms
10楼 red999         结果错误 会死循环
12楼 goal00001111   >1m
15楼 zhangyuke      结果错误 
16楼 toto996        1200ms
20楼 gangmae        结果错误
21楼 flushtime      结果错误

第二题所有代码都不合要求,经过简单的修改后只有7楼debroa723能通过简单的测试。

所以,我宣布本次比赛的冠军为debroa723,请他主持下次的编程比赛,大家鼓掌!!

回复列表 (共18个回复)

11 楼

汗,第二没人答对,让我这个没有效率的代码让大家见笑了.
让我主持下次的编程比赛,怎么主持呀?

12 楼


第一题fenix124的想法确实是非常好的,不知道是我不成熟还是怎么了,反正我是想不到的;

第二题太难了,没办法,规定时间内实在没有主意:

#include <iostream>
using namespace std;

#define out(x) (cout << #x << ": " << x << endl)

typedef long long int_64;
const int maxint = 0x7FFFFFFF;
const int_64 maxint_64 = 0x7FFFFFFFFFFFFFFFLL;
template <class T> void show(T a, int n) { for (int i = 0; i < n; ++i) cout << a[i] << ' '; cout << endl; }
template <class T> void show(T a, int r, int l) { for (int i = 0; i < r; ++i) show(a[i], l); cout << endl; }

const int maxn = 110;
const int maxm = 11;
const int mask[] = {1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323};

int n, m;
int g[maxn][maxm];
int f[maxn][59049];
int is_ok[10000];
int len;
int bits[14];

inline int get_bit(int x, int k)
{
    return x % mask[k + 1] / mask[k];
}

void DFS(int origin_state, int origin_line, int now_col, int delta)
{
    if (now_col >= m)
    {
        int new_current = 0;
        for (int i = 0; i < m; i++)
            if (bits[i] > 0)
                new_current += bits[i] * mask[i];

        f[origin_line + 1][new_current] >?= f[origin_line][origin_state] + delta;
        return;
    }
    if (bits[now_col] == -1 && g[origin_line + 1][now_col] == 0)
    {
        bits[now_col] = 2;
        DFS(origin_state, origin_line, now_col + 3, delta + 1);
        bits[now_col] = -1;
    }
    DFS(origin_state, origin_line, now_col + 1, delta);
}

void DFS1(int now_col, int new_current, int last1, int last2)
{
    if (now_col >= m)
    {
        is_ok[len++] = new_current;
        return;
    }

    if (last1 != 2 && last2 != 2)
        DFS1(now_col + 1, new_current + 2 * mask[now_col], 2, last1);
    if (last1 != 1 && last2 != 1)
        DFS1(now_col + 1, new_current + mask[now_col], 1, last1);
    DFS1(now_col + 1, new_current, 0, last1);
}

void pre_process()
{
    len = 0;
    DFS1(0, 0, -1, -1);
}

int FIND_EFS()
{
    memset(f, -1, sizeof(f));
    f[0][0] = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < len; j++)
            if (f[i][is_ok[j]] != -1)
            {
                for (int k = 0; k < m; k++)
                    bits[k] = get_bit(is_ok[j], k) - 1;
                DFS(is_ok[j], i, 0, 0);
            }
    }
    int ret = 0;
    for (int i = 0; i < mask[m]; i++)
        ret >?= f[n][i];
    return ret;
}

int main()
{
    char s[22];
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        scanf("%s", s);
        for (int j = 0; j < m; j++)
            if (s[j] == 'P')
                g[i][j] = 0;
            else
                g[i][j] = 1;
    }
    pre_process();
    printf("%d\n", FIND_EFS());
    return 0;
}

13 楼


位运算对于不是计算机专业的人异常不乐意接受!
现在真的感受到这个家伙的巨大价值了!~

14 楼


那是我的大脑高速运转了一个半小时后马上就要放弃的时候终于灵感爆发了...虽然结论很简单。

15 楼

我也做一下第二题  简单的状态dp

#include <stdio.h>

int CheckOneLine(char line[])
{
    char *s = line, *p;
    while (*s && *s!='Y') s++;
     p = s++;
    while (*s) {
        if (*s=='Y') {
            if(s-p<=2)
                return 0;
            else
                 p = s;
         }
         s++;
     }
    return 1;
}

int main( )
{
    static int DP[102][60][60]={0};
    char line[11], *row;
    int maxsta=0, i, j, k, f, s, t, li, n;
    int N, M, MAX=0, status[60]={0}, num[60]={0};
     scanf("%d %d", &N, &M);
     j = 1<<M;
    for (i=0; i<j; i++) {
        for (k=0; k<M; k++)
             line[k] = (i&(1<<k)) ? 'Y' : 'N';
         line[M] = '\0';
        if (CheckOneLine(line)) {
             status[maxsta] = i;
            for (s=i; s; s>>=1)
                if (s&1)
                     num[maxsta]++;
             maxsta++;
         }
     }
    for (k=2; k<N+2; k++) {
         scanf("%s", line);
         row = line;
         li = 0; n=0;
        while (*row) {
            if (*row=='H')
                 li |= 1<<n;
             row++; n++;
         }
        for (f=0; f<maxsta; f++)
            for (s=0; s<maxsta; s++)
                for (t=0; t<maxsta; t++) {
                    if (status[t]&li)
                        continue;
                     i = status[f];
                     j = status[s];
                     n = status[t];
                    if (i&j || i&n || j&n)
                        continue;
                    if (DP[k][s][t] < DP[k-1][f][s]+num[t])
                         DP[k][s][t] = DP[k-1][f][s]+num[t];
                    if (MAX<DP[k][s][t])
                         MAX = DP[k][s][t];
                 }
     }
     printf("%d\n", MAX);
    return 0;  
}

16 楼

后面没有贴了吗?

17 楼

2楼 fenix124        220ms
4楼 flushtime       290ms

要是我选择,我会选以上两个之一作为冠军

18 楼

不可否认,2楼和4楼的代码很优秀,如果只有一题,结果就没得怀疑,但他们怎么说都漏掉了第二题,再说,我出题的本意也在第二题,虽然说7楼的代码在第一题效率上很低,但也算提交了两道题,或许从某种程度上说,都不算AC,但我想,我们这也不是真正的ACM,注重的还是结果,其次才是效率……至于“冠军”,是种荣誉,但也过是一种责任,我也相信,debroa723很主持好下一次比赛。

我来回复

您尚未登录,请登录后再回复。点此登录或注册