总结

期望得分:\(100 + 100 + 10\)
实际得分:\(0 + 20 + 10\)

完美.

今天的考试格外完美,\(T1\)做了*\(2.5h\),最后换来了\(0\)分的好成绩,史无前例美妙绝伦,我竟然不删调试,做得™好。
\(T2\)是个好题,是个好阅读题\(n\)\(m\)写反了,样例给的是\(n\)\(m\)相等的情况,最终完美\(100—>20\),我竟然这么粗心,题目竟然没读好,做得™好.
\(T3\)没时间了,都耗在\(T1\)上了,可惜\(T1\)还没有分,做得™好.

总体来说,™好,做得™好,做的太™好了

希望以后继续粗心马虎不看好程序,创下更好的成绩

(写下这段话,嘲讽我自己)

思路

T1

先写了\(30\)分暴力,直接\(O(n^4)\)枚举

然后写\(hash\),调不出来,最后发现初始化\(hash\)的时候写错了,改完之后看着答案对,调试的东西也忘记删了,最终完美爆零

然而考完试之后,拿我的暴力程序去测试,却得了\(90\)

意思就是……我在前半个小时,就打了\(90\)分!!

然后在最后\(10\)分上杠了两个小时!

最后还错了!

麻麻我要回家,社会太险恶了

一把辛酸泪啊!

T2

由题意可得,\(m\)是行数,\(n\)是列数,只走\(23\)个拐弯,\(n\)\(m\)的范围又很小,所以就可以写\(n*m*23*4\)\(dp\)了!

\(f[i][j][k]\)表示在\((i, j)\)点走了\(k\)步获得的最大价值

因为每个点都可以重复进入,所以我们可以得到方程

\[f[i][j][k] = max(f[i][j][k], f[nx][ny][k - 1] + a[i][j])(nx,ny)是点(i, j)上下左右的四个点\]

然后就做完了

T3

首先打表找规律:

1  0
2  1
3  2        = (1 + 0) * 2
4  9        = (1 + 2) * 3
5  44       = (9 + 2) * 4
6  265      = (44 + 9)* 5
7  1854     = (265 + 44) * 6
8  14833    = ...
9  133496
10 1334961
11 14684570
12 176214841

然后发现规律是\(f[n] = (f[n - 1] + f[n - 2]) *(i - 1)\)

最后套上高精就完了

代码

T1

考场爆零代码(可能会编译失败,这告诉我,变量用\(cnm\)也不用\(hash\)

/*
By:Loceaner
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#define ull unsigned long long
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

const int N = 211;

char pa[N][N], meng[N];
int n, m, a[N], l[N], ans, cnt[N];
ull p[N], hash[N][N], sjp[N];

//void work() {
//  int len = strlen(meng + 1);
//  for(int i = 1; i <= m; i++) {
//      for(int j = 1; j <= len; j++) {
//          if(meng[j] == pa[i][1]) {
//              int sta = j, now = j, st = 1, flag = 0;
//              while(meng[now] == pa[i][st] && st <= l[i] && now <= len) {
//                  now++, st++;
//                  flag = 1;
//              }
//              if(flag) now--, st--;
//              if(st == l[i]) ans += sta * a[i];
//          }
//      }
//  }
//}

bool query(int l1, int r1,int now) {
    ull h1, h2;
    h1 = sjp[r1] - sjp[l1 - 1] * p[r1 - l1 + 1];
    h2 = hash[now][l[now]];
    return h1 == h2;
}

void work2() {//hash
    memset(sjp, 0, sizeof(sjp));
    int len = strlen(meng + 1);
    for(int i = 1; i <= len; i++) {
        sjp[i] = sjp[i - 1] * 27 + meng[i] - 'a' + 1;
    }
    for(int i = 1; i <= len; i++) cout << sjp[i] << ' ';
    cout << '\n';
    for(int i = 1; i <= m; i++) {
        for(int j = 1; j <= len; j++) {
            if(meng[j] == pa[i][1]) {
                if(query(j, j + l[i] - 1, i)) ans += j * a[i];
            }
        }
    }
}

int main() {
    freopen("dream.in", "r", stdin);
    freopen("dream.out", "w", stdout);
    n = read(), m = read();
    p[0] = 1;
    for(int i = 1; i <= 200; i++) p[i] = p[i - 1] * 27ull;
    for(int i = 1; i <= m; i++) scanf("%s", pa[i] + 1), l[i] = strlen(pa[i] + 1);
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= l[i]; j++)
            hash[i][j] = hash[i][j - 1] * 27 + pa[i][j] - 'a' + 1;
    for(int i = 1; i <= m; i++) a[i] = read();
    for(int i = 1; i <= n; i++) scanf("%s", meng + 1), work2();
    cout << ans << '\n';
    return 0;
}
/*
1 1
a
1
aaaaaaa


2 2
abc
def
1
2
abcdef
defabc
*/

可以拿\(90\)的暴力

/*
By:Loceaner
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#define ull unsigned long long
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

const int N = 211;

char pa[N][N], meng[N];
int n, m, a[N], l[N], ans, cnt[N];
ull p[N], cnm[N][N], sjp[N];

void work() {
    int len = strlen(meng + 1);
    for(int i = 1; i <= m; i++) {
        for(int j = 1; j <= len; j++) {
            if(meng[j] == pa[i][1]) {
                int sta = j, now = j, st = 1, flag = 0;
                while(meng[now] == pa[i][st] && st <= l[i] && now <= len) {
                    now++, st++;
                    flag = 1;
                }
                if(flag) now--, st--;
                if(st == l[i]) ans += sta * a[i];
            }
        }
    }
}

int main() {
    freopen("dream.in", "r", stdin);
    freopen("dream.out", "w", stdout);
    n = read(), m = read();
    for(int i = 1; i <= m; i++) scanf("%s", pa[i] + 1), l[i] = strlen(pa[i] + 1);
    for(int i = 1; i <= m; i++) a[i] = read();
    for(int i = 1; i <= n; i++) scanf("%s", meng + 1), work();
    cout << ans << '\n';
    return 0;
}
/*
1 1
a
1
aaaaaaa


2 2
abc
def
1
2
abcdef
defabc
*/

\(hash\)满分

/*
By:Loceaner
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#define ull unsigned long long
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

const int N = 211;

char pa[N][N], meng[N];
int n, m, a[N], l[N], ans, cnt[N];
ull p[N], cnm[N][N], sjp[N];


bool query(int l1, int r1,int now) {
    ull h1, h2;
    h1 = sjp[r1] - sjp[l1 - 1] * p[r1 - l1 + 1];
    h2 = cnm[now][l[now]];
    return h1 == h2;
}

void work2() {//cnm
    memset(sjp, 0, sizeof(sjp));
    int len = strlen(meng + 1);
    for(int i = 1; i <= len; i++) {
        sjp[i] = sjp[i - 1] * 27 + meng[i] - 'a' + 1;
    }
    for(int i = 1; i <= m; i++) {
        for(int j = 1; j <= len; j++) {
            if(meng[j] == pa[i][1]) {
                if(query(j, j + l[i] - 1, i)) ans += j * a[i];
            }
        }
    }
}

int main() {
    freopen("dream.in", "r", stdin);
    freopen("dream.out", "w", stdout);
    n = read(), m = read();
    p[0] = 1;
    for(int i = 1; i <= 200; i++) p[i] = p[i - 1] * 27ull;
    for(int i = 1; i <= m; i++) scanf("%s", pa[i] + 1), l[i] = strlen(pa[i] + 1);
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= l[i]; j++)
            cnm[i][j] = cnm[i][j - 1] * 27 + pa[i][j] - 'a' + 1;
    for(int i = 1; i <= m; i++) a[i] = read();
    for(int i = 1; i <= n; i++) scanf("%s", meng + 1), work2();
    cout << ans << '\n';
    return 0;
}
/*
1 1
a
1
aaaaaaa


2 2
abc
def
1
2
abcdef
defabc
*/

T2

考场\(20\)代码

/*
By:Loceaner
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#define int long long
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

const int N = 311;

int n, m, sx, sy, a[N][N], f[N][N][23];

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


signed main() {
    freopen("corner.in", "r", stdin);
    freopen("corner.out", "w", stdout);
    memset(f, -1, sizeof(f));
    n = read(), m = read();
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            a[i][j] = read();
            if(a[i][j] == 0) f[i][j][0] = 0;
        }
    }
    for(int k = 1; k <= 23; k++) {
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(a[i][j] != -1 && a[i][j] != 0) {
                    for(int l = 0; l <= 3; l++) {
                        int nx = i + dx[l], ny = j + dy[l];
                        if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && a[nx][ny] >= 0 && f[nx][ny][k - 1] != -1) {
                            f[i][j][k] = max(f[i][j][k], f[nx][ny][k - 1] + a[i][j]);
                        }
                    }
                }
            }
        }
    }
    int ans = -0x3f3f3f3f;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            ans = max(ans, f[i][j][23]);
        }
    }
    cout << ans << "\n";
    return 0;
}

改改\(m\)\(n\)之后\(ac\)

/*
By:Loceaner
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#define int long long
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

const int N = 311;

int n, m, sx, sy, a[N][N], f[N][N][23];

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


signed main() {
    freopen("corner.in", "r", stdin);
    freopen("corner.out", "w", stdout);
    memset(f, -1, sizeof(f));
    m = read(), n = read();
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            a[i][j] = read();
            if(a[i][j] == 0) f[i][j][0] = 0;
        }
    }
    for(int k = 1; k <= 23; k++) {
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(a[i][j] != -1 && a[i][j] != 0) {
                    for(int l = 0; l <= 3; l++) {
                        int nx = i + dx[l], ny = j + dy[l];
                        if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && a[nx][ny] >= 0 && f[nx][ny][k - 1] != -1) {
                            f[i][j][k] = max(f[i][j][k], f[nx][ny][k - 1] + a[i][j]);
                        }
                    }
                }
            }
        }
    }
    int ans = -0x3f3f3f3f;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            ans = max(ans, f[i][j][23]);
        }
    }
    cout << ans << "\n";
    return 0;
}

T3

正解(\(from\ gyh dalao ? : zlq\))

#include<cstdio>
#include<iostream>
#include<vector>
#include<iomanip>
#include<cassert>
#include<algorithm>
#include<cstring>
#define rg register
#define LL long long
const int MARX = 1010;
const int Big_B = 10; const int Big_L = 1;
inline int intcmp_ (int a, int b) { if (a > b) return 1; return a < b ? -1 : 0; }
struct Int
{
    inline int max(int a, int b) {return a > b ? a : b;}
    inline int min(int a, int b) {return a < b ? a : b;}
    std :: vector <int> c; Int () {}
    Int (int x) { for (; x > 0; c.push_back (x % Big_B), x /= Big_B); }
    Int (LL x) { for (; x > 0; c.push_back (x % Big_B), x /= Big_B); }
    inline void CrZ () { for (; !c.empty () && c.back () == 0; c.pop_back ()); }
    inline Int &operator += (const Int &rhs)
    {
        c.resize (max (c.size (), rhs.c.size ())); rg int i, t = 0, S;
        for (i = 0, S = rhs.c.size (); i < S; ++ i)
          c[i] += rhs.c[i] + t, t = c[i] >= Big_B, c[i] -= Big_B & (-t);
        for (i = rhs.c.size (), S = c.size (); t && i < S; ++ i)
          c[i] += t, t = c[i] >= Big_B, c[i] -= Big_B & (-t);
        if (t) c.push_back (t); return *this;
    }
    inline Int &operator *= (const Int &rhs)
    {
        rg int na = c.size (), i, j, S, ai;
        c.resize (na + rhs.c.size ()); LL t;
        for (i = na - 1; i >= 0; -- i)
        {
            ai = c[i], t = 0, c[i] = 0;
            for (j = 0, S = rhs.c.size (); j < S; ++ j)
            {
              t += c[i + j] + (LL) ai * rhs.c[j];
              c[i + j] = t % Big_B, t /= Big_B;
            }
            for (j = rhs.c.size (), S = c.size (); t != 0 && i + j < S; ++ j)
              t += c[i + j], c[i + j] = t % Big_B, t /= Big_B;
            assert (t == 0);
        }
        CrZ (); return *this;
    }
    friend inline Int operator + (const Int &lhs, const Int &rhs)
    { Int res = lhs; return res += rhs; }
    friend inline Int operator * (const Int &lhs, const Int &rhs)
    { Int res = lhs; return res *= rhs; }
    friend inline std :: ostream &operator << (std :: ostream &out, const Int &rhs)
    {
        if (rhs.c.size () == 0) out << "0";
        else
        {
          out << rhs.c.back ();
          for (rg int i = rhs.c.size () - 2; i >= 0; -- i)
            out << std :: setfill ('0') << std :: setw (Big_L) << rhs.c[i];
        }
        return out;
    }
};
//=============================================================
LL n;
Int f[MARX];
//=============================================================
inline LL read()
{
    LL s = 1, w=0; char ch=getchar();
    for(; !isdigit(ch); ch=getchar()) if(ch=='-') s =-1;
    for(; isdigit(ch); ch=getchar()) w = w*10+ch-'0';
    return s*w;
}
//=============================================================
signed main()
{
    freopen("keke.in","r",stdin);
    freopen("keke.out","w",stdout);
    n = read();
    f[1] = 0, f[2] = 1;
    if(n <= 2) { std::cout << f[n]; return 0; }
    for(rg int i = 3; i <= n; i ++) f[i] = (f[i - 1] + f[i - 2]) * (i - 1);
    std::cout << f[n];
}
01-20 02:44