hdu多校4

Problem L. Graph Theory Homework

思路:很容易想到一步从 1 走到 n 最优。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int,int>
#define piii pair<int, pair<int,int>>

using namespace std;

const int N = 2e5 + 7;
const int M = 1e4 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-10;
const double PI = acos(-1);

int n, a[N];
int main() {
    int T; scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        printf("%d
", (int)sqrt(abs(a[n] - a[1])));
    }
    return 0;
}
/*
*/
View Code

Problem K. Expression in Memories

思路:把0的情况搞清楚就好啦。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int,int>
#define piii pair<int, pair<int,int>>

using namespace std;

const int N = 2e5 + 7;
const int M = 1e4 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-10;
const double PI = acos(-1);

char s[N];
int n;
bool is(char c) {
    if(c == '+' || c == '*') return true;
    return false;
}

int main() {
    int T; scanf("%d", &T);
    while(T--) {
        scanf("%s", s + 1);
        n = strlen(s + 1);
        s[0] = '+';
        bool flag = true;

        for(int i = 2; i <= n; i++) {
            if(is(s[i]) && is(s[i - 1])) {
                flag = false;
                break;
            }
        }
        if(is(s[1]) || is(s[n])) flag = false;

        if(!flag) {
            puts("IMPOSSIBLE");
            continue;
        }

        for(int i = 1; i <= n && flag; i++) {
            if(s[i] == '0') {
                if(s[i - 1] >= '0' && s[i - 1] <= '9') continue;
                else if(is(s[i - 1])) {
                    if(i < n) {
                        if(!is(s[i + 1])) {
                            if(s[i + 1] == '?') s[i + 1] = '+';
                            else {
                                flag = false;
                                break;
                            }
                        }
                    }
                } else {
                    s[i - 1] = '1';
                }
            }
        }

        for(int i = 1; i <= n; i++) {
            if(s[i] == '?') s[i] = '1';
        }

        for(int i = 2; i <= n; i++) {
            if(is(s[i]) && is(s[i - 1])) {
                flag = false;
                break;
            }
        }

        for(int i = 1; i < n; i++) {
            if(s[i] == '0' && is(s[i - 1])) {
                if(s[i + 1] >= '0' && s[i + 1] <= '9') {
                    flag = false;
                    break;
                }
            }
        }

        if(is(s[1]) || is(s[n])) flag = false;

        if(!flag) puts("IMPOSSIBLE");
        else puts(s + 1);
    }
    return 0;
}
/*
*/
View Code

Problem E. Matrix from Arrays

思路:打表找规律发现,n为奇数的时候n * n的矩阵循环,n为偶数时2n * 2n的矩阵循环,然后就二维前缀和搞一搞。

题目没有取模我傻傻地加了取模WA了一次。。

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 100 + 7;
const int mod = 1e9 + 7;
LL M[N][N], dp[N][N];
LL A[N];
int n;
LL sum;

void init() {
    int cursor = 0;
    for (int i = 0; i <= 100; ++i) {
        for (int j = 0; j <= i; ++j) {
            M[j][i - j] = A[cursor];
            cursor = (cursor + 1) % n;
        }
    }
}

LL cal(LL x, LL y) {
    LL cnt1 = x / n, cnt2 = y / n;
    LL ans = sum * cnt1 * cnt2;
    LL num1 = x % n, num2 = y % n;

    ans += dp[num1][num2];
    ans += dp[num1][n - 1] * cnt2;
    ans += dp[n - 1][num2] * cnt1;
    return ans;
}

int main(){
    int T; scanf("%d", &T);
    while(T--) {
        scanf("%d",&n);
        memset(dp, 0, sizeof(dp));
        memset(M, 0, sizeof(M));
        sum = 0;
        for(int i = 0; i < n; i++) scanf("%d", &A[i]);
        init();

        if(n % 2 == 0) n <<= 1;

        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                sum += M[i][j];
                dp[i][j] += M[i][j];
                if(i) dp[i][j] += dp[i - 1][j];
                if(j) dp[i][j] += dp[i][j - 1];
                if(i && j) dp[i][j] -= dp[i - 1][j - 1];
            }
        }

        int q; scanf("%d", &q);
        while(q--) {
            LL x0, y0, x1, y1, ans = 0;
            scanf("%lld%lld%lld%lld", &x0, &y0, &x1, &y1);
            ans = cal(x1, y1);
            if(x0 && y0) ans += cal(x0 - 1, y0 - 1);
            if(x0) ans -= cal(x0 - 1, y1);
            if(y0) ans -= cal(x1, y0 - 1);
            printf("%lld
", ans);
        }
    }
    return 0;
}

/*
*/
View Code

Problem D. Nothing is Impossible

思路:这个题无力吐槽,题面改了又改。。 居然还有那么多人用错的题面过了题。。。

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 100 + 7;
const int mod = 1e9 + 7;

LL n, m, b[N];
int main(){
    int T; scanf("%d", &T);
    while(T--) {
        scanf("%lld%lld", &n, &m);
        for(int i = 1; i <= n; i++) {
            LL a; scanf("%lld%lld", &a, &b[i]);
        }
        LL now = 1, ans = 0;
        sort(b + 1, b + 1 + n);
        for(int i = 1; i <= n; i++) {
            now *= (b[i] + 1);
            if(now > m) break;
            ans = i;
        }
        printf("%lld
", ans);
    }
    return 0;
}

/*
*/
View Code

Problem J. Let Sudoku Rotate

思路:暴力dfs然后剪枝

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

bool did[2][16][16];
char s[20][20];

struct pos{
    int xx,yy,v;
};
vector<pos> v[5][5][16];

int ans;
void Get(int x,int y, int w)
{
    char c;
    if(w <= 9) c = w + '0';
    else c = 'A' + (w - 10);

    int xx=x/4;
    int yy=y/4;

    int i,j;
    bool judge=false;
    for(i=x;i<x+4;i++){
        for(j=y;j<y+4;j++){
            if(s[i][j]==c){
                judge=true;
                break;
            }
        }
        if(judge) break;
    }
    v[xx][yy][w].push_back({i,j,0});

    if(i%4==0&&j%4==0){
        v[xx][yy][w].push_back({i,j+3,1});
        v[xx][yy][w].push_back({i+3,j+3,2});
        v[xx][yy][w].push_back({i+3,j,3});
    }
    else if(i%4==0&&j%4==3){
        v[xx][yy][w].push_back({i+3,j,1});

        v[xx][yy][w].push_back({i+3,j-3,2});
        v[xx][yy][w].push_back({i,j-3,3});
    }
    else if(i%4==3&&j%4==0){
        v[xx][yy][w].push_back({i-3,j,1});

        v[xx][yy][w].push_back({i-3,j+3,2});
         v[xx][yy][w].push_back({i,j+3,3});
    }
    else if(i%4==3&&j%4==3){

        v[xx][yy][w].push_back({i,j-3,1});
        v[xx][yy][w].push_back({i-3,j-3,2});
         v[xx][yy][w].push_back({i-3,j,3});
    }
    ////

    else if(i%4==1&&j%4==0){

        v[xx][yy][w].push_back({i-1,j+2,1});
        v[xx][yy][w].push_back({i+1,j+3,2});
         v[xx][yy][w].push_back({i+2,j+1,3});
    }
    else if(i%4==3&&j%4==1){
        v[xx][yy][w].push_back({i-2,j-1,1});

        v[xx][yy][w].push_back({i-3,j+1,2});
         v[xx][yy][w].push_back({i-1,j+2,3});
    }
    else if(i%4==2&&j%4==3){
        v[xx][yy][w].push_back({i+1,j-2,1});

        v[xx][yy][w].push_back({i-1,j-3,2});
         v[xx][yy][w].push_back({i-2,j-1,3});
    }
    else if(i%4==0&&j%4==2){

        v[xx][yy][w].push_back({i+2,j+1,1});
        v[xx][yy][w].push_back({i+3,j-1,2});
         v[xx][yy][w].push_back({i+1,j-2,3});
    }

    //
    else if(i%4==2&&j%4==0){

        v[xx][yy][w].push_back({i-2,j+1,1});
        v[xx][yy][w].push_back({i-1,j+3,2});
         v[xx][yy][w].push_back({i+1,j+2,3});
    }
    else if(i%4==3&&j%4==2){
        v[xx][yy][w].push_back({i-1,j-2,1});

        v[xx][yy][w].push_back({i-3,j-1,2});
          v[xx][yy][w].push_back({i-2,j+1,3});
    }
    else if(i%4==1&&j%4==3){
        v[xx][yy][w].push_back({i+2,j-1,1});

        v[xx][yy][w].push_back({i+1,j-3,2});
        v[xx][yy][w].push_back({i-1,j-2,3});
    }
    else if(i%4==0&&j%4==1){

        v[xx][yy][w].push_back({i+1,j+2,1});
        v[xx][yy][w].push_back({i+3,j+1,2});
        v[xx][yy][w].push_back({i+2,j-1,3});
    }
    ////
    else if(i%4==1&&j%4==1){

        v[xx][yy][w].push_back({i,j+1,1});
        v[xx][yy][w].push_back({i+1,j+1,2});
        v[xx][yy][w].push_back({i+1,j,3});
    }
    else if(i%4==1&&j%4==2){

        v[xx][yy][w].push_back({i+1,j,1});
        v[xx][yy][w].push_back({i+1,j-1,2});
          v[xx][yy][w].push_back({i,j-1,3});
    }
    else if(i%4==2&&j%4==1){
        v[xx][yy][w].push_back({i-1,j,1});

        v[xx][yy][w].push_back({i-1,j+1,2});
        v[xx][yy][w].push_back({i,j+1,3});
    }
    else if(i%4==2&&j%4==2){

        v[xx][yy][w].push_back({i,j-1,1});
        v[xx][yy][w].push_back({i-1,j-1,2});
         v[xx][yy][w].push_back({i-1,j,3});
    }
}


void dfs(int x,int y,int step){
    if(step>=ans) return ;
    if(x==4){
        ans=min(ans,step);
        return ;
    }

        for(int i=0;i<4;i++)
        {
            bool flag = true;
            for(int w = 0; w < 16; w++) {
                int tx=v[x][y][w][i].xx,ty=v[x][y][w][i].yy;
                if(did[0][tx][w]||did[1][ty][w])
                    flag=false;
            }

            //printf("%d %d
",tx,ty);

            if(flag){
                for(int w=0;w<16;w++){
                    int tx=v[x][y][w][i].xx,ty=v[x][y][w][i].yy;
                    did[0][tx][w]=true;
                    did[1][ty][w]=true;
                }
                if(y==3){
                    dfs(x+1,0,step+v[x][y][0][i].v);
                }
                else{
                    dfs(x,y+1,step+v[x][y][0][i].v);
                }
                for(int w=0;w<16;w++){
                    int tx=v[x][y][w][i].xx,ty=v[x][y][w][i].yy;
                    did[0][tx][w]=false;
                    did[1][ty][w]=false;
                }

            }

        }

}

int main(){
    int T; scanf("%d",&T);
    while(T--){
        memset(did,false,sizeof(did));
        for(int i=0;i<16;i++)
            scanf("%s",s[i]);

        for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
                for(int w = 0; w < 16; w++)
                    v[i][j][w].clear();

        for(int i=0;i<16;i+=4)
        {
            for(int j=0;j<16;j+=4) {
                for(int k = 0; k < 16; k++)
                    Get(i, j, k);
            }
        }

        ans=1000000;
        dfs(0,0,0);
        printf("%d
",ans);
    }
}
View Code

补题****************************************************************

Problem B. Harvest of Apples

思路:这个莫队真的不好想,首先得推出公式来。。。

S(n, m + 1) = S(n, m) + C(n, m + 1)

S(n + 1, m) = 2 * S(n, m) - C(n, m)

然后搞莫队。。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int,int>
#define pLL pair<long long, long long>
#define piii pair<int, pair<int,int>>

using namespace std;

const int N = 1e5 + 7;
const int M = 1e4 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-10;
const double PI = acos(-1);
const int B = 300;

int ans[N], f[N], inv[N];
LL ret;
struct Qus {
    int n, m, id;
    bool operator < (const Qus &rhs) const {
        if(n / B == rhs.n / B) return m < rhs.m;
        return n / B < rhs.n / B;
    }
} qus[N];

int fastPow(int a, int b) {
    int ans = 1;
    while(b) {
        if(b & 1) ans = 1ll * ans * a % mod;
        a = 1ll * a * a % mod; b >>= 1;
    }
    return ans;
}

void init() {
    f[0] = 1;
    for(int i = 1; i < N; i++) f[i] = 1ll * f[i - 1] * i % mod;
    inv[N - 1] = fastPow(f[N - 1], mod - 2);
    for(int i = N - 2; i >= 0; i--) inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
}

int comb(int n, int m) {
    return 1ll * f[n] * inv[m] % mod * inv[n - m] % mod;
}

void update1(int m, int n, int op) {
    op = -op;
    ret += op * comb(n, m + 1);
    if(ret >= mod) ret -= mod;
    if(ret < 0) ret += mod;
}

void update2(int m, int n, int op) {
    if(op == 1) {
        ret += ret; if(ret >= mod) ret -= mod;
        ret -= comb(n - 1, m); if(ret < 0) ret += mod;
    } else {
        ret += comb(n - 1, m); if(ret >= mod) ret -= mod;
        ret = ret * inv[2] % mod;
    }
}



int main() {
    init();
    int q; scanf("%d", &q);
    for(int i = 1; i <= q; i++) {
        scanf("%d%d", &qus[i].n, &qus[i].m);
        qus[i].id = i;
    }

    sort(qus + 1, qus + q + 1);

    ret = 1;
    int l = 0, r = 1;
    for(int i = 1; i <= q; i++) {
        int L = qus[i].m, R = qus[i].n;
        while(r < R) update2(l, ++r, 1);
        while(l > L) update1(--l, r, 1);
        while(r > R) update2(l, r--, -1);
        while(l < L) update1(l++, r, -1);
        ans[qus[i].id] = ret;
    }
    for(int i = 1; i <= q; i++) printf("%d
", ans[i]);
    return 0;
}

/*
*/
View Code
原文地址:https://www.cnblogs.com/CJLHY/p/9405749.html