zoukankan      html  css  js  c++  java
  • 清北第二套题

                          enc
    【问题背景】
       zhx 和他的妹子聊天。
    【问题描述】
        考虑一种简单的加密算法。
        假定所有句子都由小写英文字母构成,对于每一个字母,我们将它唯一地映射到另一个字母。例如考虑映射规则:

        a->b, b->c, c->d, d->a.  那么单词 bad 就会被映射为 cba。这个映射规则的“逆映射规则”为: b->a, c->b, d->c, a->d。 对于密文 cba, 我们很容易将它解密为 bad。
        当然,这样的映射需要保证每一个字母映射到的字母是不同的(即不可以出现两个不同的字母映射到同一个字母,否则将会无法解密) 。
        一种常见的密码攻击方式被称为已知明文攻击。具体地,在你不知道映射表的情况下,给你一段明文和对应的密文,你可以推导出一些的映射规则,下一次你收到一条密文,你就可能可以解密它。现在你需要完成这样的一个系统。
    【输入格式】
       第一行包含一个字符串,仅包含小写字母,表示一段明文。
       第二行包含一个字符串,仅包含小写字母,表示这段明文对应的密文,保证两行长度相同。
       第三行包含一个字符串,仅包含小写字母,表示你需要解密的密文。
    【输出格式】
       输出共一行,表示输入中第三行密文对应的明文。如果不能解密,输出“ERROR”(不包含引号) 。注意输入可能出现不自恰的情况。
    【样例输入】
       ab
       cc
       cc
    【样例输出】
       ERROR
    【样例输入】
       ab
       ab
       c
    【样例输出】
       ERROR
    【样例输入】
       abcde
       bcdea
       cad
    【样例输出】
       bec
    【数据范围与规定】
       对于100%的数据,所有字符串长度<=1000。

    题解:模拟。水。但是出题人非常阴险,挖了一个坑,那就是当25个密文都有满足条件的对应明文字符时,剩下的那个密文字符与剩下的明文字符对应。就这样丢了10分。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define N 1100
    #define ll long long
    using namespace std;
    string s1,s2,s3;
    int l,sum=0;
    char ans[N];
    int ff[30];
    bool f[30]={0};
    int main()
    {
        freopen("enc.in","r",stdin);
        freopen("enc.ans","w",stdout);
        
        cin>>s1>>s2>>s3;
        l=s2.length();
        for (int i=0;i<l;i++)
          {
                int x=s2[i]-'a'+1,y=s1[i]-'a'+1;
              if (!ff[x]&&!f[y]) ff[x]=y,f[y]=1,sum++;
              else if (ff[x]==y) ff[x]=y;
              else
                 {
                      cout<<"ERROR"<<endl;
                      return 0;
                 }
          }
          
        if (sum==25)//特判,当25个密文字符都有对应的明文字符时,最后一个密文字符与明文字符相匹配 
          {
               int bj;
               for (int i=1;i<=26;i++)
                 if (!ff[i]) bj=i;
               for (int i=1;i<=26;i++)
                 if (!f[i]) ff[bj]=i;
          }
          
        l=s3.length();
        for (int i=0;i<l;i++)
          {
              int j=s3[i]-'a'+1;
              if (ff[j]) ans[i]=char(ff[j]+'a'-1);
              else
                 {
                      cout<<"ERROR"<<endl;
                      return 0;
                 }
          }
         
          
        cout<<ans<<endl;
        
        fclose(stdin);
        fclose(stdout);
        
        return 0;
    }
    模拟

                                                序
    【问题背景】
         zhx 给他的妹子们排序。
    【问题描述】
         zhx 有 N 个妹子,他对第 i 个妹子的好感度为ai, 且所有ai ,两两不相等。现在 N 个妹子随意站成一排,他要将她们根据好感度从小到大排序。他使用的是冒泡排序算法(详见下) 。如果排序过程中好感度为ai的妹子和好感度为aj的妹子发生了交换,那么她们之间会发生一场口角。

         现在zhx 想知道,给定妹子的初始排列,在排序完成后,最多存在多少个妹子,她们任意两人之间没发生过口角。

         正式地,考虑对数组ai进行冒泡排序,如果ai 和aj 在排序过程中发生交换,那么在两个元素之间连一条边。 你需要求出, 排序结束后, 最多存在多少个元素,其中任意两个元素之间不存在连边。冒牌排序算法如下:


    【输入格式】
        第一行两个整数 N,表示妹子数量。
        接下来一行 N 个整数ai,表示初始第 i 个妹子的好感度。
    【输出格式】
        一行一个整数,表示最多满足要求的妹子的个数。
    【样例输入】
       3
       3 1 2
    【样例输出】
       2
    【样例解释】
       {1, 2}。
    【数据规模与约定】
       对于30%的数据,1 ≤N ≤ 16。
       对于70%的数据,1 ≤ N ≤ 50。
       对于100%的数据,1 ≤ N ≤ 100000, 0 ≤ ai < N。

    题解:根据冒泡排序的性质,假定i小于j,若ai<aj则两个妹子绝对不会发生交换。因此求出最大上升子序列,他的长度即为答案。求最大上升子序列时,用上二分优化,可将时间降为o(nlogn)。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define N 100100
    #define ll long long
    using namespace std;
    int n,k=0,ans=0;
    int a[N];
    int num[N]={0};
    int f[N];
    int erfen(int l,int r,int q)
    {
        if (l>r) return l;
        int mid=(l+r)>>1;
        if (f[mid]>q) erfen(l,mid-1,q);
          else erfen(mid+1,r,q);
    }
    int main()
    {
        freopen("sort.in","r",stdin);
        freopen("sort.ans","w",stdout);
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        f[++k]=a[1];
        
        for (int i=2;i<=n;i++)
          {
              int j=erfen(0,k,a[i]);
            f[j]=a[i];
            if (j>k) k=j;
          }
          
        cout<<k<<endl;
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    二分,dp

                                           
    【问题背景】
         zhx 和他的妹子(们)做游戏。
    【问题描述】
         考虑 N 个人玩一个游戏, 任意两个人之间进行一场游戏 (共 N*(N-1)/2 场) ,且每场一定能分出胜负。现在,你需要在其中找到三个人构成“剪刀石头步”局面:三个人 A,B,C满足 A 战胜 B,B 战胜 C,C 战胜 A。
    【输入格式】
         第一行一个正整数 N,表示参加游戏的人数。
         接下来 N 行,每行 N 个数 0/1,中间没有空格隔开。第 i 行第 j 列数字为 1表示 i 在游戏中战胜了 j。所有对角线元素(即第 i 行第 i 个元素)为 0,保证数据合法。
    【输出格式】
         如果存在三个人构成“剪刀石头布”局面,输出三个人的编号(从 1 开始) 。
         如果不存在这样的三个人,输出一个数-1。
    【样例输入】
         5
         00100
         10000
         01001
         11101
         11000
    【样例输出】
         1 3 2
    【数据规模与约定】
         对于55%的数据。1 ≤ N ≤ 500。
         对于80%的数据,1 ≤ N ≤ 1000。
         对于100%的数据,1 ≤ N ≤ 5000

    题解:原谅本蒟蒻不会此题,只会打最简单的暴力。弱弱的30分。由于题目没规定输出顺序,本应该能稳过55%的数据,最后只得30分。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define N 5100
    #define ll long long
    using namespace std;
    int n;
    char ch;
    bool f[N][N]={0},ff=1;
    int main()
    {
        freopen("game.in","r",stdin);
        freopen("game.ans","w",stdout);
        
        scanf("%d",&n);
        scanf("%c",&ch);
        for (int i=1;i<=n;i++)
          {
              for(int j=1;j<=n;j++)
                {
                     scanf("%c",&ch); 
                     f[i][j]=int (ch-'0');
              }
            scanf("%c",&ch);
             
          } 
         for (int i=1;i<=n;i++)
           for (int j=1;j<=n;j++)
             if (f[i][j])
               for (int k=1;k<=n;k++)
                 if (f[j][k]&&f[k][i]) 
                   {
                         cout<<i<<' '<<j<<' '<<k<<endl;
                         return 0;
                   }
        cout<<-1<<endl;
            
        fclose(stdin);
        fclose(stdout);
        
        return 0;
    }
    暴力枚举,30
  • 相关阅读:
    Velocity的使用小记
    fastJson的SerializeFilter使用
    快捷的时间转化
    How to execute a Stored Procedure with Entity Framework Code First
    自定义 ASP.NET Identity Data Model with EF
    Asp.Net Core get client IP
    HTTP 请求头中的 X-Forwarded-For
    HttpRequest,WebRequest,HttpWebRequest,WebClient,HttpClient 之间的区别
    【逻辑】500桶酒,找毒酒
    Asp.Net Core 输出 Word
  • 原文地址:https://www.cnblogs.com/sjymj/p/6000750.html
Copyright © 2011-2022 走看看