• 2020 CCPC Wannafly Winter Camp Day1


    https://ac.nowcoder.com/acm/contest/3979

    B,

    密码学

    题意是每行给你一个x,y表示第x个字符串对第y个字符串加密

    加密的方式是将字符换成数字,然后x的字符加上y的字符模52再变回字符。如果x小于y,则你的x将重复直至大于等于y

    模拟,不过你得倒序模拟

    #include<bits/stdc++.h>
    using namespace std;
    string s[1001];
    int x[1001],y[1001];
    int getnum(char c)
    {
        if(c>='a'&&c<='z') return c-'a';
        else return c-'A'+26;
    }
    char getword(int x)
    {
        if(x<26) return 'a'+x;
        else return x-26+'A';
    }
    int main()
    {
    //    cin>>s[1]>>s[2];
    //    cout<<s[1]<<s[2]<<endl;
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=m;i++)cin>>x[i]>>y[i];
        for(int i=1;i<=n;i++)cin>>s[i];
        for(int i=m;i>=1;i--){
            int l=x[i],r=y[i];
            int sz1=s[l].size();
            int sz2=s[r].size();
            for(int j=0;j<sz2;j++){
                int t=getnum(s[l][j%sz1]),t2=getnum(s[r][j]);
                s[r][j]=getword((t2-t+52)%52);
            }
        }
        for(int i=1;i<=n;i++) cout<<s[i]<<endl;
    }
    

      H

      首先我们得知的是gcd(k,y)的值必须的是唯一,你不能出现gcd(y,其他数)==gcd(y,k)这样就不能用来判断k是不是他给的x;

    好了已经知道gcd(k,y)是唯一的,接下来就是其他的东西了

    既然是唯一的就得避免gcd出来的值是1,因为这样的话当k是质数,y可以是1,y是质数也可以,不满足题目;

    故你的y必须是k的倍数,这样当k是质数时也不出问题,所以ans=k;(基础的一倍)

    接下来就是y必须是p的倍数,(p为素数且pk<=n)因为p是素数所以在gcd时不影响他的结果,这样就会导致A给了B是k,给你pk,当时通过gcd你无法正确判断了(gcd(y,k)=gcd(y,pk))

    所以我们需要将素数部分全部乘起来再乘以ans,

    由于特殊情况当500内的素数全部相乘,数字会超大

    我们用大数相乘

    #include<bits/stdc++.h>
    using namespace std;
     
    int p[505], n, m, i, j, t, k, l, a[2000];
    bool vis[505];
    void mul(int n)
    {
        for(int i=0;i<1000;i++) a[i]*=n;
        for(int i=0;i<1000;i++){
            a[i+1]+=a[i]/10000;
            a[i]=a[i]%10000;
        }
    }
    void prin()
    {
        int i=1000;
        while(i>=0&&!a[i]) i--;
        printf("%d",a[i--]);
        while(i>=0) printf("%04d",a[i--]);
    }
    int main() {
        //freopen("in.txt", "r", stdin);
        n = 500;
        for (i = 2; i <= n; i++) {   //线筛
            if (!vis[i]) p[m++] = i;
            for (j = 0; j < m && i*p[j] <= n; j++) {
                vis[i*p[j]] = 1;
                if (i%p[j] == 0) break;
            }
        }
        scanf("%d", &t);
        while (t--) {
            scanf("%d%d", &n, &k);
            memset(a, 0, sizeof(a));
            a[0] = l = 1;
            for (i = 0; i < m && k*p[i] <= n; i++) mul(p[i]);
            mul(k);
    //        for (i = l - 1; ~i; i--) printf("%d", a[i]);
            prin();
            puts("");
        }
    }
    

      第k大数查询

    通过二分这个值

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #define LL long long
    using namespace std;
    const int maxn = 1e5 + 5;
     
    LL a[maxn], b[maxn];
    LL n, m, k;
     
    bool che(LL mid) {
        LL num = 0;
        for (int i = 1; i <= m; i++) {
            if (b[i] == 0) num += mid < 0 ? n : 0;
            if (b[i] < 0) num += lower_bound(a + 1, a + n + 1, ceil((double)mid / b[i])) - (a + 1);
            if (b[i] > 0) num += n - ((upper_bound(a + 1, a + n + 1, floor((double)mid / b[i]))) - (a + 1));
        }
        return num <= k;
    }
     
    int main() {
        cin >> n >> m >> k;
        k--;
        for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        for (int i = 1; i <= m; i++) scanf("%lld", &b[i]);
        sort(a + 1, a + n + 1);
        sort(b + 1, b + m + 1);
        LL l = -1e13, r = 1e13;
        while (l + 1 < r) {
            LL mid = (l + r) >> 1;
            if (che(mid))r = mid;
            else l = mid;
        }
        cout << r << endl;
        return 0;
    }
    

      

  • 相关阅读:
    查找和排序-6.快速排序
    查找和排序-5.插入排序
    PAT (Basic Level) Practice (中文)1093、1094
    srand((unsigned)time(NULL))详解
    fscanf()库函数
    C++ fopen函数用法
    简单计数排序
    数据结构:堆排序
    数据结构:归并排序
    团体程序设计天梯赛-练习集(八)(DFS,7-37 整数分解为若干项之和、7-22 龟兔赛跑)
  • 原文地址:https://www.cnblogs.com/hgangang/p/12251665.html
Copyright © 2020-2023  润新知