Wannafly挑战赛18

体验不佳

A

不难发现 -2 和 0.5 必须同时出现 2k,kZ 2 k , k ∈ Z 次 才能保证 a[1]=a[n]=1
所以:

for(int i = 4; i < n; i += 4) {
    ans += f(n - 1, i);//同时出现 i/2 个 -2 和 i/20.5 的方案数
    ans %= MOD;
}
// By: chutzpah  Blog: blog.csdn.net/ctsas
#include <iostream>
#include <queue>
#include <vector>
#include <map>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;

const int INF = 0x3f3f3f3f;
const int MAXN = (int)1e3 + 5;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-8;
const double PI = acos(-1.0);

int mod_pow(int a, int n) {
    int res = 1;
    while(n) {
        if(n&1) res = 1LL * res * a % MOD;
        a = 1LL * a * a % MOD;
        n >>= 1;
    }
    return res;
}

int fac[MAXN], inv[MAXN];
int C(int a, int b) {
    if(a == b || b == 0) return 1;
    return 1LL * fac[a] * mod_pow(fac[b], MOD - 2) % MOD * mod_pow(fac[a - b], MOD - 2) % MOD;
}

int f(int n, int i) {
    return 1LL * C(n, i / 2) * C(n - i / 2,i / 2) % MOD;
}

int main() {
    inv[0] = inv[1] = fac[0] = 1;
    for(int i = 1; i < MAXN; ++i) fac[i] = 1LL * i * fac[i - 1] % MOD;
    for(int i = 2; i < MAXN; ++i) inv[i] = 1LL * inv[MOD % i] * (MOD - MOD / i) % MOD;
    int n;
    scanf("%d", &n);
    int ans = 1;
    for(int i = 4; i < n; i += 4) {
        ans += f(n - 1, i);
        ans %= MOD;
    }
    printf("%d\n", ans);
    return 0;
}

B

ans=[1(12p)n]/2 a n s = [ 1 − ( 1 − 2 p ) n ] / 2

// By: chutzpah  Blog: blog.csdn.net/ctsas
#include <iostream>
#include <queue>
#include <vector>
#include <map>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;

const int INF = 0x3f3f3f3f;
const int MAXN = (int)1e6 + 5;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-8;
const double PI = acos(-1.0);

int mod_pow(int a, int n) {
    int res = 1;
    while(n) {
        if(n&1) res = 1LL * res * a % MOD;
        a = 1LL * a * a % MOD;
        n >>= 1;
    }
    return res;
}

char s[MAXN];

int main() {
    int a, n = 0;
    scanf("%d%s", &a, s);
    int len = strlen(s);
    for(int i = 0; i < len; ++i) {
        n = (1LL * n * 10 + s[i] - '0') % (MOD - 1);
    }
    int ans = 1LL * (1 + MOD - mod_pow(1LL * ((5000 - a + MOD) % MOD) * mod_pow(5000, MOD - 2) % MOD, n)) % MOD * mod_pow(2, MOD - 2) % MOD;
    printf("%d\n", ans);
}

我一直都这么写 唯独 newcoder 出问题???!!!

    int len = strlen(s);
    for(int i = 0; i < len; ++i) {
        n = (1LL * n * 10 + s[i] - '0') % (MOD - 1);
    }
写成
    for(int i = 0; i < s[i]; ++i) {
        n = (1LL * n * 10 + s[i] - '0') % (MOD - 1);
    }
导致wa 8次,不知道为什么

C

瞎暴力

期望可能是小数,需要想第一题那么做,但是题面没说啊!!!!

// By: chutzpah  Blog: blog.csdn.net/ctsas
#include <iostream>
#include <queue>
#include <vector>
#include <map>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;

const int INF = 0x3f3f3f3f;
const int MAXN = (int)2e3 + 5;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-8;
const double PI = acos(-1.0);

int x[MAXN], y[MAXN];
int sx[MAXN], sy[MAXN];
ll dsx[MAXN], dsy[MAXN];

int mod_pow(int a, int n) {
    int res = 1;
    while(n) {
        if(n&1) res = 1LL * res * a % MOD;
        a = 1LL * a * a % MOD;
        n >>= 1;
    }
    return res;
}

bool gc() {
    char res;
    while((res = getchar()) <= 32);
    return res == '1';
}

int main() {
    int n, m, cnt = 0;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= m; ++j) {
            if(gc()) {
                ++x[i];
                ++y[j];
                ++cnt;
            }
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; ++i) {
        for(int k = 1; k <= n; ++k) {
            dsx[i] += 1LL * abs(i - k) * x[k] % MOD;
            dsx[i] %= MOD;
        }
    }
    for(int i = 1; i <= m; ++i) {
        for(int k = 1; k <= m; ++k) {
            dsy[i] += 1LL * abs(i - k) * y[k] % MOD;
            dsy[i] %= MOD;
        }
    }
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= m; ++j) {
            ans ^= (dsx[i] + dsy[j]) * mod_pow(cnt, MOD - 2) % MOD;
        }
    }
    printf("%d\n", ans );
    return 0;
}

D

4维dp,需要记录步数(可以压缩成2,我们只需要上一步的所有状态)\横坐标\纵坐标\方向(5个方向)

dp[2][MAXN][MAXN][5];

如此状态转移也就很显然了

// By: chutzpah  Blog: blog.csdn.net/ctsas
#include <iostream>
#include <queue>
#include <vector>
#include <map>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;

const int INF = 0x3f3f3f3f;
const int MAXN = (int)2e2 + 5;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-8;
const double PI = acos(-1.0);

int dp[2][MAXN][MAXN][5];
const int ox[] = {0, 0, 0, 1, -1};
const int oy[] = {0, 1, -1, 0, 0};

int main() {
    int n, m, t, x1, y1, D, x2, y2;
    cin >> n >> m >> t >> x1 >> y1 >> D >> x2 >> y2;
    int o = 0;
    dp[o][1][1][0] = 1;
    for(int s = 0; s < t; ++s, o = 1 - o) {
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
                for(int k = 0; k < 5; ++k)
                    dp[1 - o][i][j][k] = 0;
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= m; ++j) {
                int add = 0;
                for(int k = 0; k < 5; ++k) (add += dp[o][i][j][k]) %= MOD;
                for(int k = 1; k < 5; ++k) {
                    int x = i + ox[k];
                    int y = j + oy[k];
                    if (x > n || x <= 0 || y > m || y <= 0) continue;
                    if (max(abs(x1 - i) , abs(y1 - j)) <= D) {
                        (dp[1 - o][x][y][k] += (dp[o][i][j][0] + dp[o][i][j][k]) % MOD) %= MOD;
                    } else {
                        (dp[1 - o][x][y][k] += add) %= MOD;
                    }
                }
                (dp[1 - o][i][j][0] += add) %= MOD;
            }
        }
    }
    int ans = 0;
    for(int k = 0; k < 5; ++k) (ans += dp[o][x2][y2][k]) %= MOD;
    printf("%d\n", ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值