2016.8.30.第40套测试题

Problems
1. 潜伏者
(spy.pas/c/cpp)
【问题描述】
R 国和S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动。
历经艰险后,潜伏于S 国的R 国间谍小C 终于摸清了S 国军用密码的编码规则:
1、 S 国军方内部欲发送的原信息经过加密后在网络上发送,原信息的内容
与加密后所的内容均由大写字母‘A’—‘Z’构成(无空格等其他
字母)。
2、 S 国对于每个字母规定了对应的“密字”。加密的过程就是将原信息中
的所有字母替换为其对应的“密字”。
3、 每个字母只对应一个唯一的“密字”,不同的字母对应不同的“密字”。
“密字”可以和原字母相同。
例如,若规定‘A’的密字为‘A’,‘B’的密字为‘C’(其他字母及密字略),则
原信息“ABA”被加密为“ACA”。
现在,小C 通过内线掌握了S 国网络上发送的一条加密信息及其对应的原信息。小C
希望能通过这条信息,破译S 国的军用密码。小C 的破译过程是这样的:扫描原信息,对
于原信息中的字母x(代表任一大写字母),找到其在加密信息中的对应大写字母y,并认
为在密码里y 是x 的密字。如此进行下去直到停止于如下的某个状态:
1、 所有信息扫描完毕,‘A’—‘Z’所有26 个字母在原信息中均出现过
并获得了相应的“密字”。
2、 所有信息扫描完毕,但发现存在某个(或某些)字母在原信息中没有出
现。
3、 扫描中发现掌握的信息里有明显的自相矛盾或错误(违反S 过密码的编
码规则)。例如某条信息“XYZ”被翻译为“ABA”就违反了“不同
字母对应不同密字”的规则。
在小C 忙得头昏脑胀之际,R 国司令部又发来电报,要求他翻译另外一条从S 国刚刚
截取到的加密信息。现在请你帮助小C:通过内线掌握的信息,尝试破译密码。然后利用破
译的密码,翻译电报中的加密信息。

解析:

很简单,就是三个数组,一个记录翻译,两个记录会不会违反规则。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char passages[105],keys[105],words[105];
int lp,lk,lw,exchange[30];
bool f1[30],f2[30];
bool flag=false;
int main()
{
    freopen("spy.in","r",stdin);
    freopen("spy.out","w",stdout);
    cin>>keys>>passages>>words;
    lp=strlen(passages);
    lw=strlen(words);
    for(int i=0;i<lp;i++)
    {
        int j=passages[i]-'A'+1;
        int k=keys[i]-'A'+1;
        if(f1[j]!=f2[k]||(exchange[k]&&exchange[k]!=j)) { flag=true; break; }
        exchange[k]=j;
        f1[j]=f2[k]=true;
    }
    for(int i=1;i<=26;i++) if(f1[i]==false) { flag=true; break; }
    if(flag) { cout<<"Failed"<<endl; return 0; }
    for(int i=0;i<lw;i++)
    {
        int j=words[i]-'A'+1;
        char t=exchange[j]+'A'-1;
        cout<<t;
    }
    return 0;
}

 

2. Hankson的趣味题
(son.pas/c/cpp)
【问题描述】
Hanks博士是BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫Hankson。现在,刚刚放学回家的Hankson正在思考一个有趣的问题。
今天在课堂上,老师讲解了如何求两个正整数c1和c2的最大公约数和最小公倍数。现在Hankson认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0,a1,b0,b1,设某未知正整数x满足:
1、 x和a0的最大公约数是a1;
2、 x和b0的最小公倍数是b1。
Hankson的“逆问题”就是求出满足条件的正整数x。但稍加思索之后,他发现这样的x并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的x的个数。请你帮助他编程求解这个问题。

解析:

我最开始用了一个短代码,90,TLE了一个点,然后看大神的代码,发现可以只算根号b1那么多。因为分解b1的因数嘛,相乘肯定一定啊。所以一次性不用全部循环完。结果还是T了一个点,百思不得其解,然后何神一来,看都不看,你用ll肯定挂啊。然后才反应过来int运算比ll快,而一开始为了保险起见,用的ll定义,其实该题是可以用int的。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
ll a0,a1,b0,b1,a2,b2,s;
int n,ans;
ll gcd(ll v,ll u)
{
    ll x,y;
    if(v>u) x=v,y=u;
    else x=u,y=v;
    if(y==1) return 1;
    if(x%y==0) return y; 
    return gcd(y,x%y);
}
int main()
{
    freopen("son.in","r",stdin);
    freopen("son.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        ans=0;
        cin>>a0>>a1>>b0>>b1;//能被b1整除,能整除a1; 
        a2=a0/a1;//x与 a2 互质 与b0
        b2=b1/b0;//x一定有的 a1 b2 
        s=gcd(a1,b2); 
        s=(a1/s)*b2;
        for(ll j=s;j<=b1;j+=s)
        if((gcd(j,a0)==a1)
        &&((b0/gcd(b0,j)*j)==b1))
        {
            ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
}

解析:

暴搜dfs+几个剪枝

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#define ll long long
using namespace std;
struct stu{
    int x,y,dire;
}ans[10];
int n,a;
struct st{
    int w[10][15];
}map;
void down(int v)
{
    if(map.w[v][0]<3) return ;
    int sum[10];
    sum[0]=0;
    for(int j=1;j<=map.w[v][0];j++)
    if(map.w[v][j]==map.w[v][j-1]) sum[j]=sum[j-1]+1;
    else sum[j]=1;
    for(int j=map.w[v][0];j>=3;)
    if(sum[j]>=3) 
    {
        for(int k=j-sum[j]+1;k<=sum[j];k++)
            map.w[v][k]=map.w[v][k+sum[j]];
            map.w[v][0]-=sum[j];
    }
    else j--;
}
void clean()
{
    for(int i=1;i<=5;i++)
    down(i);
}
void dfs(int step)
{
    if(step>n) 
    {
        for(int i=1;i<=5;i++)
        if(map.w[i][1]>0) return ;
        for(int i=1;i<=n;i++)
        cout<<ans[i].x<<' '<<ans[i].y<<' '<<ans[i].dire<<endl;  
        exit(0);
    }
    st ma=map;
    for(int i=1;i<=5;i++)
        for(int j=1;j<=map.w[i][0];j++)
        {
            if(i<5)
            {
                int t=map.w[i+1][j];
                map.w[i+1][j]=map.w[i][j];
                map.w[i][j]=t;
                ans[step].x=i-1;
                ans[step].y=j-1;
                ans[step].dire=1;
                clean();
                dfs(step+1);
                map=ma;
            }
            if(i>1&&map.w[i-1][j]==0)
            {
                int t=map.w[i-1][j];
                map.w[i-1][j]=map.w[i][j];
                map.w[i][j]=t;
                ans[step].x=i-1;
                ans[step].y=j-1;
                ans[step].dire=-1;
                clean();
                dfs(step+1);
                map=ma;
            }
        }
}
int main()
{
    freopen("mayan.in","r",stdin);
    freopen("mayan.out","w",stdout);
    cin>>n;
    for(int i=1;i<=5;i++)
    {
        int j=0;
        while(cin>>a&&a)
        {
            j++;
            map.w[i][j]=a;
            map.w[i][0]=j;
        }
    }
    dfs(1);
    cout<<"-1"<<endl;
    return 0;
}

 

posted @ 2016-08-30 17:25  sci  阅读(223)  评论(0编辑  收藏  举报