第十二届北航程序设计竞赛预赛

https://biancheng.love/contest-ng/index.html#/123/problems

题目链接

A、C看懂题意就好了。

G题,贪心,最大的数肯定要越高位越好,所以尽量放1,剩3就放7,次大就调过来。特判下4没了。

D题,求出每个点需要推到的概率然后加起来。

M题,贪心可得,大乘小对应起来,然后求次数,就用类似求一个个环,假如不对应的环就需要环内点个数-1次来交换。因为假如环内有x个点,你交换x-1次,最后一个也会排好序了

L题,用几个数组维护一下每个点四个方向最远能到达的点,然后求T就枚举中间那个点,L就枚举左下角那个点,求S就枚举最上面的两个点,n^3

F题,一个多边形,它夹角对应的都要放在整数点上,那只能是正方形了,多边形面积是一个n·[(a^2)/4]·cot(π/n),然后cot好像只有几个特殊点才是有理数吧,如果坐标都在整数点上,那面积肯定可以割割割,反正是个有理数,大概是这样证明的。所以问题就变成从n个点选4个能否组成正方形,把全部点hash起来,然后枚举正方形任意两个点,再判断另外两个点是否存在就行了,复杂度是n^2,光看数据以为会T就加了个读入挂,不知道有没有其他做法。

K题,我们先把这个东西的类似层次遍历的图画一画,就会发现,其实答案会是某层状态最多的方案数量,然后题目就转化成了将若干个数分成n堆,每一堆都有不同的限制di。然后就是dp搞,dp[i][j]表示前i堆分了j个的方案数,然后dp[i][j] = sum(dp[i-1][k])(0<=k<=j&&j-k<di)了为什么小于,因为每一堆上原本就有一个1的,然后求max(dp[n][k])(0<k<若干个数)就是答案了。

B题,首先我瞎做的时候是毫无思路的,于是就自己做起了小学加法题,然后发现每进位一次,原本的数位和就会-9,好了,然后就开始搞了,从L+到R,进位M次,我们需要先能快速求出0-x之间所有数的数位和,这个我们可以用类似拆位来递归下去,先预处理出0-(10^k - 1)之间的数位和,这个比较简单

sum[0] = 0,sum[i] = sum[i-1]*10 + 45*10^(i-1);

那这样我们就可以拆位算下去了,比如求434

我们先算

0 - 99 = sum[2]

100 - 199 = 1 * 10^2 + sum[2]

200 - 299 = 2 * 10^2 + sum[2]

300 - 399 = 3 * 10^2 + sum[2]

400 - 434 我们可以把最前面那个4的贡献单独求出来 = 4 * 35

然后再 + 递归(34)

会求这个之后,我们先暴力求一下最高上界会是多少。。算出来发现挺小的,于是我就把上界设为3e7了,

二分一下R

变成(Cnt(R) - Cnt(L-1) - 暴力求数位和((L+R)*(R-L+1)/2) )/ 9这个就是进位次数了,然后把R逼近上界就行了

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << 63) - 1;
const LL mod = 1000000007;
const int N = 1e5 + 5;
const double Pi = acos(-1.0);
const int maxn = 2e5 + 5;
int main() {
#ifdef local
    freopen("in", "r", stdin);
#endif
    int T;
    cin>>T;
    while(T--){
        unsigned long long x,n;
        cin>>x>>n;
        for(int i = 0 ;i  < n ; i++){
            x<<=1;
            x|=1;
        }
        cout<<x<<endl;
    }
}
A
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << 63) - 1;
const LL mod = 1000000007;
const int N = 1e5 + 5;
const double Pi = acos(-1.0);
const int maxn = 2e5 + 5;
int c[10];
struct node {
    int point;
    bool flag;
} now[10];
void init() {
    c[1] = 4;
    c[2] = 3;
    c[3] = 5;
    c[4] = 6;
    c[5] = 4;
    c[6] = 6;
    c[7] = 5;
    c[8] = 4;
    c[9] = 3;
}
char s[105];
int main() {
#ifdef local
    freopen("in", "r", stdin);
#endif
    init();
    int T;
    cin >> T;
    while(T--) {
        int res = 0 ;
        for(int i = 1 ; i <= 9 ; i++) {
            for(int j = 0 ; j < 9; j++) {
                now[j].flag = 1;
            }
            for(int j = 0 ; j < c[i]; j++) {
                scanf("%d", &now[j].point);
            }
            for(int z = 0 ; z < 2 ; z++)
                for(int j = 0 ; j < c[i]; j++) {
                    scanf("%s", s);
                    if(s[0] - '0' < 3) {
                        now[j].flag = 0;
                    }
                }
            for(int j = 0 ; j < c[i]; j++) {
                if(now[j].flag){
                    res += now[j].point;
                }
            }
        }
        cout<<res<<endl;
    }
}
C
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << 63) - 1;
const LL mod = 1000000007;
const int N = 1e5 + 5;
const double Pi = acos(-1.0);
const int maxn = 2e5 + 5;
int main() {
#ifdef local
    freopen("in", "r", stdin);
#endif
    int T;
    cin>>T;
    while(T--){
        int n;
        cin>>n;
        if(n==4){
            puts("11 4");
            continue;
        }
        string big = "";
        while(n > 6){
            big =big + "1";
            n -= 2;
        }
        if(n==6){
            printf("111");
            cout<<big<<" ";
            printf("77");
            cout<<big<<endl;
        }
        else if(n==5){
            printf("71");
            cout<<big<<" ";
            printf("17");
            cout<<big<<endl;
        }
    }
}
G
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << 63) - 1;
const LL mod = 1000000007;
const int N = 1e5 + 5;
const double Pi = acos(-1.0);
const int maxn = 1e5 + 5;
namespace IO {

const int MT = 5e7; //1e711000kb

char buf[MT];

int c, sz;

void begin() {

    c = 0;

    sz = fread(buf, 1, MT, stdin);

}

inline bool read(int &t) {

    while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;

    if(c >= sz) return false;

    bool flag = 0;

    if( buf[c] == '-')flag = 1, c++;

    for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';

    if(flag) t = -t;

    return true;

} inline bool read(char s[]) {

    while(c < sz && (buf[c] == ' ' || buf[c] == '\n')) c++;

    if(c >= sz) return false;

    int len = 0;

    while(c < sz && buf[c] != ' ' && buf[c] != '\n') s[len++] = buf[c] , c++;

    s[len] = 0;

    return true;

}

}
using namespace IO;
int fa[maxn];
bool vis[maxn];
int n;
struct node {
    int val, id;
    bool operator < (const node & a)const {
        return val < a.val;
    }
} X[maxn], Y[maxn];
int main() {
#ifdef local
    freopen("in", "r", stdin);
#endif
    begin();
    int T;
    read(T);
    while(T--) {
        int n;
        read(n);
        for(int i = 1; i <= n ; i++) {
            read(X[i].val);
            X[i].id = i;
        }
        for(int i = 1 ; i <= n ; i++) {
            read(Y[i].val);
            Y[i].id = i;
        }
        sort(X + 1, X + n + 1);
        sort(Y + 1, Y + n + 1);
        LL res = 0;
        for(int i = 1; i <= n; i++) {
            res += 1LL * X[i].val * Y[n - i + 1].val;
        }
        for(int i = 1; i <= n; i++) {
            int uid = X[i].id;
            int vid = Y[n - i + 1].id;
            fa[uid] = vid;
        }
        int cnt = 0;
        for(int i = 1 ; i <= n; i++) {
            if(!vis[i]) {
                int len = 0;
                int u = i;
                while(!vis[u]) {
                    vis[u] = 1;
                    u = fa[u];
                    len++;
                }
                cnt += len - 1;
            }
        }
        cout << res << " " << cnt << endl;
        memset(vis, 0, sizeof vis);
    }
}
M
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << 63) - 1;
const LL mod = 1000000007;
const int N = 1e5 + 5;
const double Pi = acos(-1.0);
const int maxn = 200 + 5;
int L[maxn][maxn];
int R[maxn][maxn];
int U[maxn][maxn];
int D[maxn][maxn];
char s[maxn][maxn];
int n , m;
void gao() {
    for(int i = 1; i <= n; i++) {
        s[i][0] = '#';
        for(int j = 1; j <= m; j++) {
            s[0][j] = '#';
            if(s[i][j] != '#') {
                if(s[i][j - 1] != '#')
                    L[i][j] = L[i][j - 1];
                if(s[i - 1][j] != '#')
                    U[i][j] = U[i - 1][j];
            }
        }
    }
    for(int i = n; i >= 1; i--) {
        s[i][m + 1] = '#';
        for(int j = m; j >= 1; j--) {
            s[n + 1][j] = '#';
            if(s[i][j] != '#') {
                if(s[i][j + 1] != '#')
                    R[i][j] = R[i][j + 1];
                if(s[i + 1][j] != '#')
                    D[i][j] = D[i + 1][j];
            }
        }
    }
}
void init() {
    cin >> n >> m;
    for(int i = 0; i <= 105; i++) {
        for(int j = 0 ; j <= 105; j++) {
            L[i][j] = j;
            R[i][j] = j;
            U[i][j] = i;
            D[i][j] = i;
        }
    }
}
int main() {
#ifdef local
    freopen("in", "r", stdin);
#endif
    int cas;
    cin >> cas;
    while(cas--) {
        init();
        for(int i = 1; i <= n; i++) {
            scanf("%s", s[i] + 1);
        }
        gao();
        int _T = 0, _L = 0, _S = 0;
        for(int i = 1 ; i <= n ; i++) {
            for(int j = 1; j <= m ; j++) {
                if(s[i][j] != '#') {
                    int _l = j - L[i][j] + 1;
                    int _r = R[i][j] - j + 1;
                    int _d = D[i][j] - i + 1;
                    int _u = i - U[i][j] + 1;
                    int _k = (min(_l, _r) << 1) - 1;
                    if(min(_l, _r) >= 2 && _d >= 3) {
                        if(_k <= _d)
                            _T += min(_l, _r) - 1;
                        else {
                            _T += (_d - 1)/ 2;
                        }
                    }
                    if(min(_u, _r) >= 2) {
                        _L += min(_u, _r) - 1;
                    }
                    for(int z = j + 2; z <= R[i][j]; z++) {
                        int l = z - j + 1;
                        if(_d < l)break;
                        int ni = l + i - 1;
                        int nr = R[ni][j] - j + 1;
                        if(nr < l)continue;
                        int _ni = ni, _nj = z;
                        int _nd = D[_ni][_nj] - _ni + 1;
                        if(_nd < l)continue;
                        int __ni = _ni + l - 1, __nj = _nj;
                        int __k = __nj - L[__ni][__nj] + 1;
                        if(__k >= l) {
                            _S++;
//                        cout<<"--------"<<endl;
//                        cout<<i<<" "<<j<<endl;
//                        cout<<z<<endl;
//                        cout<<_ni<<" "<<_nj<<endl;
//                        cout<<__ni<<" "<<__nj<<endl;
//                        cout<<"--------"<<endl;
                        }
                    }
                }
            }
        }
        cout << _T << " " << _L << " " << _S << endl;
    }
}
L
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << 63) - 1;
const LL mod = 1000000007;
const int N = 1e5 + 5;
const double Pi = acos(-1.0);
const int maxn = 200 + 5;
namespace IO {

const int MT = 5e7; //1e711000kb

char buf[MT];

int c, sz;

void begin() {

    c = 0;

    sz = fread(buf, 1, MT, stdin);

}

inline bool read(int &t) {

    while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;

    if(c >= sz) return false;

    bool flag = 0;

    if( buf[c] == '-')flag = 1, c++;

    for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';

    if(flag) t = -t;

    return true;

} inline bool read(char s[]) {

    while(c < sz && (buf[c] == ' ' || buf[c] == '\n')) c++;

    if(c >= sz) return false;

    int len = 0;

    while(c < sz && buf[c] != ' ' && buf[c] != '\n') s[len++] = buf[c] , c++;

    s[len] = 0;

    return true;

}

}
using namespace IO;
struct point {
    int x, y;
}points[maxn];
struct node {
    int x, y;
    int next;
} T[maxn];
int head[maxn];
int top;
void build(point p) {
    int sum = (1LL * p.x * p.x + 1LL * p.y * p.y) % maxn;
    T[top].x = p.x;
    T[top].y = p.y;
    T[top].next = head[sum];
    head[sum] = top++;
}
bool query(point p) {
    int sum = (1LL * p.x * p.x + 1LL * p.y * p.y) % maxn;
    int q = head[sum];
    while(q != -1) {
        if( T[q].x == p.x && T[q].y == p.y ) {
            return 1;
        }
        q = T[q].next;
    }
    return 0;
}
int main() {
#ifdef local
    freopen("in", "r", stdin);
#endif
    begin();
    int T;
    read(T);
    while(T--) {
        int n;
        read(n);
        top = 0;
        int x, y;
        memset(head, -1, sizeof head);
        for(int i = 0; i < n; i++) {
            read(x);
            read(y);
            points[i].x = x << 1;
            points[i].y = y << 1;
            build(points[i]);
        }
        if(n < 4) {
            puts("-1");
            continue;
        }
        int g, h, u, v;
        point a, b;
        bool flag = 0;
        for(int i = 0 ; i < n && !flag; i++) {
            for(int j = i + 1; j < n ; j++) {
                g = (points[i].x + points[j].x);
                h = (points[i].y + points[j].y);
                u = (points[j].x - points[i].x);
                v = (points[i].y - points[j].y);
                a.x = (g - v) / 2;
                a.y = (h - u) / 2;
                b.x = (v + g) / 2;
                b.y = (h + u) / 2;
                if(query(a) && query(b)) {
                    flag = 1;
                    break;
                }
            }
        }
        if(flag)puts("4");
        else puts("-1");
    }
}
F
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << 63) - 1;
const LL mod = 1000000007;
const int N = 1e5 + 5;
const double Pi = acos(-1.0);
const int maxn = 2e6 + 5;
int dp[25][maxn];
int sum[25][maxn];
int d[25];
int n , m;
int gao() {
    dp[0][0] = 1;
    sum[0][0] = 1;
    for(int i = 1; i <= m; i++)sum[0][i] = 1;
    for(int i = 1; i <= n; i++){
        for(int j = 0; j <= m; j++){
            if(j < d[i]){
                dp[i][j] = sum[i-1][j];
            }
            else dp[i][j] = sum[i-1][j] - sum[i-1][j-d[i]];
            sum[i][j] = (j?sum[i][j-1]:0) + dp[i][j];
        }
    }
    int res = 0;
    for(int i = 0; i <= m; i++){
        res = max(dp[n][i],res);
    }
    return res;
}

int main() {
#ifdef local
    freopen("in", "r", stdin);
#endif
    int cas;
    cin >> cas;
    while(cas--) {
        cin>>n;
        m = - n;
        for(int i = 1 ; i <= n ; i++){
            scanf("%d",&d[i]);
            m += d[i];
        }
        cout<<gao()<<endl;
    }
}
K
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << 63) - 1;
const LL mod = 1000000007;
const int N = 1e5 + 5;
const double Pi = acos(-1.0);
const int maxn = 2e6 + 5;
LL sum[15];
int gao(LL a) {
    int res = 0;
    while(a) {
        res += a % 10;
        a /= 10;
    }
    return res;
}
int Cnt(int n) {
    if(n < 10)return n * (n + 1) / 2;
    int d = log10(n);
    int p = ceil(pow(10, d));
    int tst = n / p;
    return tst * sum[d] + (tst * (tst - 1) / 2) * p + tst * (1 + n % p) + Cnt(n % p);
}
int upcnt(LL &res , LL b) {
    LL c = res;
    res += b;
    int up = 0;
    int d = 0;
    while(b || c) {
        if( (d = d + b % 10 + c % 10) > 9 )up++;
        d /= 10;
        b /= 10;
        c /= 10;
    }
    return up;
}
LL pai(LL l, LL m) {
    LL res = 0;
    int g = 0;
    for(LL i = l ; ; i++) {
        g += upcnt(res, i);
        if(g > m) {
            return res - i;
            //return i-1;
        }
    }
}
int main() {
#ifdef local
    freopen("in", "r", stdin);
#endif
    for(int i = 1; i <= 10; i++) {
        sum[i] = sum[i - 1] * 10 + 45 * ceil(pow(10, i - 1));
    }
    int T;
    cin >> T;
    while(T--) {
        LL L, M;
        cin >> L >> M;
        int d = Cnt(L - 1);
        int l = L , r = L + 2e7;
        LL res = 0;
        while(l <= r ) {
            LL mid = ( l + r ) >> 1;
            //  cout<<(mid + L) * (mid - L + 1) / 2<<endl;
            int now = gao((mid + L) * (mid - L + 1) / 2);
            int diff = Cnt(mid) - d - now;
            diff /= 9;
            if(diff <=  M) {
                l = mid + 1;
                res = (mid + L) * (mid - L + 1) / 2;
            } else r = mid - 1;
        }
        cout << res << endl;
    }

}
B

 

posted @ 2016-12-12 12:36  scau_zk  阅读(160)  评论(0编辑  收藏  举报