2018 Multi-University Training Contest 4

Problem B. Harvest of Apples

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 50;
typedef long long ll;
const ll mod = 1e9 + 7;
ll fac[maxn], sing[maxn], inv[maxn];
void init(int n)
{
    fac[0] = sing[0] = inv[0] = fac[1] = sing[1] = inv[1] = 1;
    for(int i = 2; i <= n; i++)
    {
        fac[i] = fac[i - 1] * i % mod;
        sing[i] = (mod - mod / i) * sing[mod % i] % mod;
        inv[i] = inv[i - 1] * sing[i] % mod;
    }
}
ll C(int n, int m)
{
    ll res =  fac[n]* inv[m] % mod * inv[n - m] % mod;
   // printf("%d %d %lld\n",n, m, res);
    return res;
}
struct Seg
{
    int l, r, belong, id;
}seg[maxn];
ll ans[maxn];
bool cmp(Seg A, Seg B)
{
    if(A.belong == B.belong) return A.r < B.r;
    return A.l < B.l;
}
int main()
{
    init(1e5 + 5);
    int block = sqrt(1e5);
    int T; scanf("%d", &T);
    for(int p = 1; p <= T; p++)
    {
        scanf("%d %d", &seg[p].l, &seg[p].r);
        seg[p].belong = seg[p].l / block;
        seg[p].id = p;
    }
    sort(seg + 1, seg + T + 1, cmp);
    int l = 0, r = 0;
    ll res = 1;
    for(int i = 1; i <= T; i++)
    {
        while(l < seg[i].l)
        {
            res = (res * 2LL % mod + mod - C(l, r)) % mod;
            l++;
        }
        while(l > seg[i].l)
        {
            l--;
            res = (res + C(l, r)) * sing[2] % mod;
        }
        while(r < seg[i].r)
        {
            r++;
            res = (res + C(l, r)) % mod;
        }
        while(r > seg[i].r)
        {
            res = (res + mod - C(l, r)) % mod;
            r--;
        }
        ans[seg[i].id] = res;
       // printf("%lld\n", ans[seg[i].id]);
    }
    for(int i = 1; i <= T; i++)
    {
        printf("%lld\n", ans[i]);
    }
    return 0;
}
Code

Problem E. Matrix from Arrays

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 50;
int a[maxn];
int sum = 0;
int m[50][50];
int L;
ll solve(ll x, ll y)
{
    x++, y++;
    ll res = 0;
    int cntx = x / (2 * L);
    int cnty = y / (2 * L);
    res += (ll)cntx * cnty * sum; ///加上整块的
    int tempx = x - cntx * 2 * L;
    int tempy = y - cnty * 2 * L;
    ll sum1 = 0 ,sum2 = 0;
    for(int i = 0; i < tempx; i++) ///加上半块半块的
    {
        for(int j = 0; j < 2 * L; j++)
        {
            sum1 += m[i][j];
        }
    }
    for(int i = 0; i < 2 * L; i++)
    {
        for(int j = 0; j < tempy; j++)
        {
            sum2 += m[i][j];
        }
    }
    res += sum1 * cnty;
    res += sum2 * cntx;
    ///加上残块的
    for(int i = 0; i < tempx; i++)
    {
        for(int j = 0; j < tempy; j++)
        {
            res += m[i][j];
        }
    }
    return res;
}

int main()
{
    int T; scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &L);
        sum = 0;
        for(int i = 0; i < L; i++) scanf("%d", &a[i]), sum += 4 * L * a[i];
        int cur = 0;
        for(int i = 0; i < 45; i++)
        {
            for(int j = 0; j <= i; j++)
            {
                m[j][i - j] = a[cur];
                cur = (cur + 1) % L;
            }
        }
       /* for(int i = 0; i < 10; i++)
        {
            for(int j = 0; j < 10; j++)
            {
                printf("%3d ", m[i][j]);
            }
            printf("\n");
        }*/
       // printf("%lld\n",solve(1, 2));
        int q; scanf("%d", &q);
        while(q--)
        {
            int x1, y1, x2, y2;
            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
            ll ans = solve(x2, y2) - solve(x2, y1 - 1) - solve(x1 - 1, y2) + solve(x1 - 1, y1 - 1);
           // printf("%lld %lld %lld %lld\n",solve(x2, y2), solve(x2, y1 - 1), solve(x1 - 1, y2), solve(x1 - 1, y1 - 1));
            printf("%lld\n", ans);
        }
    }
    return 0;
}
Code

Problem J. Let Sudoku Rotate

#include <bits/stdc++.h>
using namespace std;

char s[20][20], w[5][5];
int vis[50];
int ans = 100;
int tmp[5][5];
void Rota(int a, int b) ///顺时针旋转90度
{
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            tmp[j][3 - i] = s[a + i][b + j];
        }
    }
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            s[a + i][b + j] = tmp[i][j];
        }
    }
}
int cnt = 0;
int check(int a, int b)
{
    ///memset(vis, 0, sizeof(vis)); 从dls那里学了个姿势,不用每次memset了
    for(int i = a; i < a + 4; i++)  ///判断我这个小块的前面有没有重复的
    {
        cnt++;
        for(int j = 0; j < b + 4; j++)
        {
           // printf("%d\n", s[i][j]);
            if(vis[s[i][j]] == cnt)
            {
                //printf("%d %d %d\n", i, j, cnt);
                return 0;
            }
            vis[s[i][j]] = cnt;
        }
    }
    for(int i = b; i < b + 4; i++)
    {
        cnt++;
        for(int j = 0; j < a + 4; j++)
        {
            if(vis[s[j][i]] == cnt)
                return 0;
            vis[s[j][i]] = cnt;
        }
    }
    return 1;
}
void dfs(int x, int y, int sum)
{
    if(x == 4)
    {
        ans = min(ans, sum);
        return;
    }
    if(sum >= ans) return;
    if(y == 4) return dfs(x + 1, 0, sum);
    for(int i = 0; i < 4; i++)
    {
        if(check(x * 4, y * 4))
        {
            dfs(x, y + 1, sum + i);
        }
        Rota(x * 4, y * 4);
    }
}
int main()
{
    int T; scanf("%d", &T);
    while(T--)
    {
        for(int i = 0; i < 16; i++) scanf("%s", s[i]);
        for(int i = 0; i < 16; i++)
        {
            for(int j = 0; j < 16; j++)
            {
                s[i][j] = s[i][j] - '0';
            }
        }
        memset(vis, 0, sizeof(vis));
        ans = 100;
        cnt = 0;
        dfs(0, 0, 0);
        printf("%d\n", ans);
    }
    return 0;
}
Code

Problem G. Depth-First Search

猜你喜欢

转载自www.cnblogs.com/littlepear/p/9417334.html