zoukankan      html  css  js  c++  java
  • CCPC-Wannafly Winter Camp Day 1

    B. 密码学

    题意:

    告诉你关于字符串加密的方法,然后给你一些加密操作和加密后的字符串,让你求原来的串

    思路:

    知道被加密后的串与加密字符可以向前推出被加密之前的串,不断向前模拟即可

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
     using namespace std;
     const int maxn=1020;
    char s[maxn][105];
     int b[maxn][105];
     struct node{
         int x,y;
     }a[maxn];
     int n,m,len[maxn],tem[105];
    void repair(int x,int y) {
         for(int i=0;i<len[y];i++) tem[i]=b[x][(i%len[x])];
        for(int i=0;i<len[y];i++) b[y][i] = (b[y][i]-tem[i]+52) % 52;
    }
    
    int main() {
        cin>>n>>m;
        for(int i=m;i>=1;i--) cin>>a[i].x>>a[i].y;
         for(int i=1;i<=n;i++){
             cin>>s[i];
             len[i]=strlen(s[i]);
         }
        for(int i=1;i<=n;i++){
            for(int j=0;j<len[i];j++){
                if(s[i][j]>='a'&&s[i][j]<='z')
                    b[i][j]=s[i][j]-'a';
                else if(s[i][j]>='A'&&s[i][j]<='Z')
                    b[i][j]=s[i][j]-'A'+26;
            }
        }
         for(int i=1;i<=m;i++)repair(a[i].x,a[i].y);
        for(int i=1;i<=n;i++){
            for(int j=0;j<len[i];j++){
                if(b[i][j]>=0&&b[i][j]<=25)
                    s[i][j]=b[i][j]+'a';
                else if(b[i][j]>=26&&b[i][j]<=51)
                    s[i][j]=(b[i][j]-26)+'A';
            }
        }
        for(int i=1;i<=n;i++)
            cout<<s[i]<<endl;
        return 0;    
      } 

    H. 最大公约数

    思路:

    从k开始累乘k的倍数并且为素数的数

    记得要用大数!!没发现爆了WA了好几发

    #include<bits/stdc++.h>
    using namespace std;
    
    int t,n,k;
    string ans,str;
    void initial(string &a, string &b){
        while (a.size()<b.size())a = '0' + a;
        while (b.size()<a.size())b = '0' + b;
    }
    //打印
    void print(string &a, string &b){
        cout << a << endl;
        cout << b << endl;
    }
    //找出最大的字符串
    void findMax(string &a, string &b){
        string tmp;
        if (a<b){
            tmp = b;
            b = a;
            a = tmp;
        }
    }
    //删除第一个字符'0'
    bool del(string &a){
        if (a[0] == '0'){
            a.erase(0, 1);
            return true;
        }
        else
            return false;
    }
    //删除前面所有的 0
    void delAllZroe(string &a){
        while (del(a)){
            del(a);
        };
    }
    //大数加法
    string bigItergeAdd(string a, string b){
        initial(a, b);
        a = '0' + a;
        b = '0' + b;
        for (int i = a.size() - 1; i >= 0; i--){
            int num1 = a[i] - '0';
            int num2 = b[i] - '0';
            if (num1 + num2>9){
                a[i - 1] = a[i - 1] - '0' + 1 + '0';
                a[i] = (num1 + num2) - 10 + '0';
            }
            else{
                a[i] = (num1 + num2) + '0';
            }
        }
        del(a);
        //    cout<<a<<endl;
        return a;
    }
    //大数减法
    string bigItergeSub(string a, string b){
        initial(a, b);
        findMax(a, b);
        for (int i = a.size() - 1; i >= 0; i--){
            int num1 = a[i] - '0';
            int num2 = b[i] - '0';
            if (num1<num2){
                a[i - 1] = a[i - 1] - '0' - 1 + '0';
                a[i] = (num1 + 10 - num2) + '0';
            }
            else{
                a[i] = (num1 - num2) + '0';
            }
        }
        del(a);
        //    cout<<a<<endl;
        return a;
    }
    //大数乘法(大数加法实现)
    string bigItergeMul(string a, string b){
        delAllZroe(a);
        delAllZroe(b);
        initial(a, b);
        findMax(a, b);
        string res = "0";
        int count = 0;
        delAllZroe(b);
        for (int i = b.size() - 1; i >= 0; i--){
            int num1 = b[i] - '0';
            if (i != b.size() - 1)        a = a + '0';
            for (int i = 1; i <= num1; i++){
                res = bigItergeAdd(res, a);
            }
        }
        delAllZroe(res);
        return res;
    }
    
    bool prime(int x)
    {
        for(int i=2;i<=sqrt(x);i++)
        {
            if(x%i==0) return false;
        }
        return true;
     } 
    int main()
    {
        cin>>t;
        while(t--)
        {
            cin>>n>>k;
            int temp=k;
            ans="";
            while(temp)
            {
                ans+=temp%10+'0';
                temp/=10;
            }
            reverse(ans.begin(),ans.end());
            for(int i=2;i*k<=n;i++)
            {
                if(prime(i))
                {
                    str="";
                    temp=i;
                    while(temp)
                    {
                       str+=temp%10+'0';
                       temp/=10;
                    }
                  //  cout<<str<<endl;
                    reverse(str.begin(),str.end());
                    ans=bigItergeMul(ans,str);
                }
            }
            
            cout<<ans<<endl;
        }        
    }

    F. 乘法

    题意:

    给你一个由两个数组a,b相乘构成的矩阵C,求矩阵中第K大的数

    思路:

    先将b数组排序,之后在从-1e12到1e12中二分答案,特别要注意a数组中小于0时在b数组中二分的情况,与a元素等于0时的情况

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    const int maxn=1e5+10;
    using namespace std;
    typedef long long ll;
     ll a[maxn],b[maxn];
     int n,m;
     ll ans,k;
     ll find(ll temp,ll x)
     {
         int l=1,r=m,mid,ret;
             if(x>0){
                 ret=m+1;
                 while(l<=r){
                     mid=(l+r)>>1;
                     if(b[mid]*x>=temp)    r=(ret=mid)-1;
                     else    l=mid+1;
                 }
                 return m-ret+1;
             }
            else if(x<0){
                ret=0;
                while(l<=r){
                    mid=(l+r)>>1;
                    if(b[mid]*x>=temp)    l=(ret=mid)+1;
                    else r=mid+1;
                }
                return ret;
            }
    }
     ll  judge(ll mid)
     {
         ll cnt=0;
         for(int i=1;i<=n;i++){
             if(a[i]==0)
                 cnt+=(0>=mid)*m;
             else
                 cnt+=find(mid,a[i]);
         }
        return cnt;
     }
     int main()
     {
         scanf("%d%d%lld",&n,&m,&k);
         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
         for(int i=1;i<=m;i++) scanf("%d",&b[i]);
         sort(b+1,b+1+m);
         ll l=-1e12,r=1e12;
         while(l<=r){
             ll mid=(l+r)/2;
             if(judge(mid)>=k)    l=(ans=mid)+1;
             else r=mid-1;
         }
        cout<<ans<<endl;
     }
  • 相关阅读:
    框架集。样式表
    2017.11.23知识点整理
    HTML5的标签
    HTML5大体概括截图
    2017.11.21 通用标签及属性
    2017.11.21 课程随记
    JavaScript数组
    JavaScript语句
    javascript基础知识
    不用alert提示的非空表单验证
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12185331.html
Copyright © 2011-2022 走看看