BUPT 2019 summer training warm up #-1

传送门

A、类似于拓扑排序,利用异或的性质。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define ll long long;
#define MAXN 65540 //2^16 = 65536
using namespace std;
typedef pair<int, int> P;
int degree[MAXN], s[MAXN], vis[MAXN];
queue<int> q;
queue<P> ans;
int main(){
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++){
        scanf("%d%d", &degree[i], &s[i]);
        if(degree[i] == 1) q.push(i);
   }
   while(!q.empty()){
       int u = q.front(), v; q.pop();
       v = s[u];
       if(vis[u]) continue;
       ans.push(make_pair(u, v));
       s[v] = s[v] ^ u;
       degree[v]--;
       if(degree[v] == 0) vis[v] = 1;
       if(degree[v] == 1) q.push(v);
   }
   printf("%d\n", ans.size());
   while(!ans.empty()){
       P p = ans.front(); ans.pop();
       printf("%d %d\n", p.first, p.second);
   }
   return 0;
}

B、背xiagao

#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<vector>
using namespace std;
static const int MAXN = 1005;
int a[MAXN], vis[MAXN];
int main(){
    int n, m, Min, ans;
    while(scanf("%d", &n) && n != 0){
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        scanf("%d", &m);
        if(m < 5){
            printf("%d\n", m);
            continue;
        }
        Min = ans = m;
        memset(vis, 0, sizeof(vis));
        vis[m] = 1;
        sort(a + 1, a + 1 + n);
        for (int i = 1; i <= n; i++)
        {
            ans = min(ans , Min - a[i]);
            bool flag = false;
            for (int j = a[i] + 5; j <= m; j++){
                if(!flag && vis[j]){
                    flag = true;
                    Min = min(Min, j - a[i]);
                }
                if(vis[j] == 1) vis[j - a[i]] = 1;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

C、

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long;
#define INF 0x3f3f3f3f
using namespace std;
int a[2050];
int brother(int node){
    return node % 2 == 0 ? node + 1 : node - 1;
}
int father(int node){
    return node / 2;
}
int main(){
    int n, Sum = 0;
    scanf("%d", &n);
    for (int i = 2; i < pow(2, n + 1); i++)
        scanf("%d", &a[i]);
    for (int i = pow(2, n + 1) - 1; i > 1; i--){
        if(a[i] < a[brother(i)]) Sum += a[brother(i)] - a[i];
        if(i & 1) a[father(i)] += max(a[i], a[brother(i)]);
    }
    printf("%d", Sum);
    return 0;
}

D、图,无边变有边

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long;
using namespace std;
int g[510][510], color[510];
int main(){
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    while(m--){
        scanf("%d%d", &u, &v);
        g[u][v] = g[v][u] = 1;
    }
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= n; j++){
            if(i == j)
                continue;
            if(g[i][j] == 0){
                if(color[i] == 0) color[i] = 1;
                if(color[j] == color[i]){
                    printf("No");
                    return 0;
                }
                color[j] = 4 - color[i];
            }
            else if(color[i] + color[j] == 4){
                printf("No");
                return 0;
            }
        }
    }
    for (int i = 1; i <= n; i++) if(!color[i]) color[i] = 2; 
    printf("Yes\n");
    for(int i = 1; i <= n; i++) printf("%c", char(color[i] + 'a' - 1));
    return 0;
}

E、简单数学 乘变除防溢出

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
int main(){
    long long l, r, k;
    bool flag = false;
    cin >> l >> r >> k;
    for (long long i = 1;; i = i * k)
    {
        if(i >= l){
            cout << i << " ";
            flag = true;
        }
        if(k > r / i) break;
    }
    if(!flag) cout << "-1";
    return 0;
}

F、简单数论,辗转相除

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll solve(ll a, ll b){
    return b == 0 ? 0 : a / b + solve(b, a % b);
}
int main(){
    ll a, b;
    scanf("%lld%lld", &a, &b);
    printf("%lld", solve(a, b));
    return 0;
}

G、将10分解为2*5

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long;
using namespace std;
static const int INF = 0x3f3f3f3f;
typedef struct{
    int num2, num5;
} D;
const int dir[2][2] = {{1, 0}, {0, 1}};
D d[1010][1010];
int n, sx, sy;
int a[1010][1010], dp2[1010][1010], dp5[1010][1010], p2[1010][1010], p5[1010][1010];
int count_num(int x, int num){
    int cnt = 0;
    while(x % num == 0){
        x /= num;
        cnt++;
    }
    return cnt;
}
void print2(int x, int y){
    if(x == 1 && y == 1) return;
    if(p2[x][y] == 0){
        print2(x - 1, y);
        printf("D");
    } else{
        print2(x, y - 1);
        printf("R");
    }
}
void print5(int x, int y){
    if(x == 1 && y == 1) return;
    if(p5[x][y] == 0){
        print5(x - 1, y);
        printf("D");
    } else{
        print5(x, y - 1);
        printf("R");
    }
}
int main(){
    scanf("%d", &n);
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= n; j++){
            scanf("%d", &a[i][j]);
            if(!a[i][j]){
                d[i][j].num2 = d[i][j].num5 = 1;
                sx = i, sy = j;
            }
            else{
                dp2[i][j] = dp5[i][j] = INF;
                d[i][j].num2 = count_num(a[i][j], 2);
                d[i][j].num5 = count_num(a[i][j], 5);
            }
        }
    }
    dp2[1][1] = d[1][1].num2;
    dp5[1][1] = d[1][1].num5;
    for (int x = 1; x <= n; x++){
        for (int y = 1; y <= n; y++){
            for (int k = 0; k < 2; k++){
                int nx = x + dir[k][0], ny = y + dir[k][1];
                if(nx > n || ny > n || a[nx][ny] == 0) continue;
                if(dp2[x][y] + d[nx][ny].num2 < dp2[nx][ny]){
                    dp2[nx][ny] = dp2[x][y] + d[nx][ny].num2;
                    p2[nx][ny] = k;
                }
                if(dp5[x][y] + d[nx][ny].num5 < dp5[nx][ny]){
                    dp5[nx][ny] = dp5[x][y] + d[nx][ny].num5;
                    p5[nx][ny] = k;
                }
            }
        }
    }
    if(sx > 0 && min(dp2[n][n], dp5[n][n]) > 1){
        printf("1\n");
        for (int i = 1; i < sx; i++) printf("D");
        for (int i = 1; i < n; i++) printf("R");
        for (int i = sx; i < n; i++) printf("D");
        return 0;
    }
    if(dp2[n][n] < dp5[n][n]){
        printf("%d\n", dp2[n][n]);
        print2(n, n);
    }
    else{
        printf("%d\n", dp5[n][n]);
        print5(n, n);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值