A Great Alchemist

输入三条等长的s1,s2,s3,字符均为大写字母,且个数是偶数。

用s1和s2中一样的元素个数来构造s3。


分析:将s1,s2,s3转化为ele1[26],ele[26],goal[26],对应这些变量分别存放三个字符串中的A~Z字符个数。

分别有

x0 x1 x2 x3...x25

y0 y1 y2 y3...y25

z0 z1 z2 z3...z25


结果用每个对应x,y构造z,假设上面的结果就是符合要求的结果。于是有:

y25 - x25(范围是确定的,且奇偶性不变,即可选的结果是一个等差数列)

我们需要的结果就是y25-x25 + y24 - x24......y0 - x0 = 0成立。


因此,只需要构造y25-x25的范围,然后拓展至y0-x0的范围,即从后向前叠加范围,只需要考虑判断叠加后的范围,满足最小范围是小于等于0,最大范围大于等于0,然后最大值是偶数。就可以断定这个肯定可以实现,否则不能实现。代码如下。


// edit by colin
// 20141102
// RGF campus recruitment test
#include <iostream>
#include <cstring>
using namespace std;

int ele1[27];
int ele2[27];
int goal[27];

int rangemin[27];
int rangemax[27];

int main()
{
 //   freopen("in.txt","r",stdin);
    string s1,s2,s3;
    cin>>s1;
    cin>>s2;
    cin>>s3;

    unsigned int tmp;
    unsigned int len = s1.length();
    int mark = 0;
    // 存储三列数组
    for(int i = 0; i < len; ++i){
        tmp = s1[i] - 'A';
        ++ele1[tmp];
        tmp = s2[i] - 'A';
        ++ele2[tmp];
        tmp = s3[i] - 'A';
        ++goal[tmp];
    }
    rangemax[26] = 0;
    rangemin[26] = 0;
    for(int i=25;i>=0;--i)
    {
        if(ele1[i]+ele2[i]<goal[i]){
            cout<<"NO"<<endl;
            return 0;
        }
        // 获取x的最大最小值
        int min,max;
        if(goal[i]>=ele2[i])
            min = goal[i] - ele2[i];
        else
            min = 0;
        max = goal[i]>ele1[i]?ele1[i]:goal[i];
        // 最大最小差值,拓展范围
        rangemin[i] = goal[i] - max*2 + rangemin[i+1];
        rangemax[i] = goal[i] - min*2 + rangemax[i+1];
        //cout<<max<<" "<<min<<" "<<goal[i]<<" "<<ele1[i]<<" "<<ele2[i]<<" "<<rangemin[i]<<" "<<rangemax[i]<<endl;
    }
        // 判断最小范围,最大范围,最大值是否为偶数
    if(rangemin[0]<=0 && rangemax[0]>=0 && rangemax[0]%2 == 0)
        mark = 1;
    if(mark)
        cout<<"YES"<<endl;
    else
        cout<<"NO"<<endl;
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值