2019百度之星第二场初赛 A, B, C

8 篇文章 0 订阅
5 篇文章 0 订阅

A、度度熊与数字

 

直接暴力枚举V的因子

找到答案之后对答案排一下序输出即可;

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

const int maxn = 1005;
int arr[1000] = {1};
int arrr[1000] = {1};
int factor(int n) {
    if(n == 1) return 1;
    int count1 = 1, num = sqrt(n);
    for (int i = 2; i <= num; i++) {
        if (!(n % i)) {
            arr[count1++] = i;
            arr[count1++] = n / i;
        }
    }
    if (n == (num*num)) arr[count1++] = num;
    arr[count1++] = n;
    return count1;
}
int main() {
    int T, n;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        int cnt = factor(n);
        int m = n, sum = 0;
        while(m) {
            sum += m % 10;
            m /= 10;
        }
        int ans = 1;
        sort(arr, arr + cnt);
        cnt = unique(arr, arr + cnt) - arr;
        for(int i = 1; i < cnt; i++) {
            int x = arr[i];
            if(sum % x == 0) {
                arrr[ans++] = x;
            }
        }
        printf("%d\n",ans);
        for(int i = 0; i < ans - 1; i++) {
            printf("%d ", arrr[i]);
        }
        printf("%d\n", arrr[ans - 1]);
    }
    return 0;
}

 

 

B、度度熊与排列

 

从1-m枚举p,找到满足第一个字符串的位置p,然后枚举剩下的所有串,判断是否满足这个p,如果满足,由于是从小到大枚举,那么一定是字典序最小的,p[i] 就是这个值,否则往后继续找

 

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 +10;
char A[30][55],B[30][55];
int p[55], vis[55];
int T, n, m, f;
int solve(){
    for(int j = 1; j <= m; j++) {
        int flag = 0;
        for(int k = 1; k <= m; k++) {
            if(!vis[k] && A[1][j] == B[1][k]) {
                flag = 1;
                for(int i = 2; i <= n; i++) {
                    if(A[i][j] != B[i][k]) {
                        flag = 0;
                        break;
                    }
                }
                if(flag) {
                    p[j] = k;
                    vis[k] = 1;
                    break;
                }
            }
        }
        if(!flag) return -1;
    }
    return 1;
}
int main() {
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &n, &m); 
        for(int i = 1; i <= n ;i++) {
            scanf("%s%s",A[i] + 1, B[i] + 1);
        }
        memset(vis, 0, sizeof(vis));
        int flag = solve();
        if(flag == 1) {
            for(int j = 1; j <= m; j++) {
                printf("%d%c", p[j], " \n"[j == m]);
            }
        }
        else
            puts("-1");
    }
    return 0;
}

 

 

C、度度熊与运算式 1

 

 

判断最终结果的每一位是否能够被构造出来,能构造出来的话,就让他构造一次,如果构造多次,按位异或可能会让这一位变成0,由于数字1按位异或只会影响最后一位,所以我们不管最后一位,先把前面的位构造出来,剩下偶数个1异或 就是0,奇数个就是1

 

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 3e6 +10;
char s[maxn];
int vis[30], T;
int main() {
    scanf("%d", &T);
    while(T--) {
        scanf("%s", s + 1);
        int len = strlen(s + 1);
        int cnt = 1;
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i<= len; i++) {
            if(s[i] == '^') {
                for(int j = 21; j > 0; j--) {
                    if(cnt >= (1 << j) && !vis[j]) {
                        vis[j] = 1;
                        cnt -= (1 << j);
                    }
                }
                cnt = 1;
            }
            else cnt++;
        }
        for(int j = 21; j > 0; j--) {
            if(cnt >= (1 << j) && !vis[j]) {
                vis[j] = 1;
                cnt -= (1 << j);
            }
        }
        int ans = 0;
        for(int i = 21; i > 0; i--) {
            if(vis[i]) ans += (1 << i);
        }
        ans += (len + 1 - ans) % 2;
        printf("%d\n", ans);
    }
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值