首页 > 其他 > 详细

【题解】 2015 ACM/ICPC Asia Regional Shenyang Online

时间:2015-09-24 11:03:12      阅读:296      评论:0      收藏:0      [点我收藏+]

【1006】 FangFang (暴力枚举)

Fang Fang

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 871    Accepted Submission(s): 364


Problem Description
Fang Fang says she wants to be remembered.
I promise her. We define the sequence F of strings.
F0 = f",
F1 = ff",
F2 = cff",
Fn = Fn?1 + f", for n > 2
Write down a serenade as a lowercase string S in a circle, in a loop that never ends.
Spell the serenade using the minimum number of strings in F, or nothing could be done but put her away in cold wilderness.
 

Input
An positive integer T, indicating there are T test cases.
Following are T lines, each line contains an string S as introduced above.
The total length of strings for all test cases would not be larger than 106.
 

Output
The output contains exactly T lines.
For each test case, if one can not spell the serenade by using the strings in F, output ?1. Otherwise, output the minimum number of strings in F to split Saccording to aforementioned rules. Repetitive strings should be counted repeatedly.
 

Sample Input
8 ffcfffcffcff cffcfff cffcff cffcf ffffcffcfff cffcfffcffffcfffff cff cffc
 

Sample Output
Case #1: 3 Case #2: 2 Case #3: 2 Case #4: -1 Case #5: 2 Case #6: 4 Case #7: 1 Case #8: -1
Hint
Shift the string in the first test case, we will get the string "cffffcfffcff" and it can be split into "cffff", "cfff" and "cff".
 

Source
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:  5467 5466 5463 5462 5461 
 


题意是找最小的划分 子串在题中已给出 f ff cff cfff cf4 cf5 cf6 cfn 这样只要暴力判两个c之间f的数目即可 如果存在两个c之间f小于2 说明不可划分 否则一定会划分成c的数量个区间 也就是划分的最小数量为c的数量 另外 如果没c 就划分成len/2+len%2 即全划ff或f

额外需要注意的是有空串和其余字符还有串是环串 首尾连在一起的。。。


代码如下:

#include <bits/stdc++.h>

using namespace std;

char str[1111111];
int pos[1111111];
int tp;

int main()
{
    int t,i,z,cnt,f,len;
    scanf("%d",&t);
    getchar();
    for(z = 1; z <= t; ++z)
    {
        gets(str);
        tp = 0;
        f = 1;
        for(i = 0; str[i]; ++i)
        {
            if(str[i] == 'c') pos[tp++] = i;//记录每个c的位置
            else if(str[i] != 'f') f = 0;//有其余字符
        }

        len = strlen(str);
        printf("Case #%d: ",z);
        if(!f) puts("-1");//有其余字符
        else if(tp == 0)//没有c
        {
            printf("%d\n",len/2+len%2);
        }
        else
        {
            for(i = 0; i < tp-1; ++i)
            {
                if(pos[i+1]-pos[i]-1 < 2)//两个c之间f数量小于2
                {
                    f = 0;
                    break;
                }
            }
            if(len-1-pos[tp-1]+pos[0] < 2) f = 0;//特判第一个c和最后一个 因为是成环切割
            if(f)
            {
                printf("%d\n",tp);
            }else puts("-1");
        }
    }
    return 0;
}

【1010】 Jesus Is Here (斐波那契+推公式)

Jesus Is Here

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)
Total Submission(s): 360    Accepted Submission(s): 255


Problem Description
I‘ve sent Fang Fang around 201314 text messages in almost 5 years. Why can‘t she make sense of what I mean?
``But Jesus is here!" the priest intoned. ``Show me your messages."
Fine, the first message is s1=c" and the second one is s2=ff".
The i-th message is si=si?2+si?1 afterwards. Let me give you some examples.
s3=cff"s4=ffcff" and s5=cffffcff".

``I found the i-th message‘s utterly charming," Jesus said.
``Look at the fifth message". s5=cffffcff" and two cff" appear in it.
The distance between the first cff" and the second one we said, is 5.
``You are right, my friend," Jesus said. ``Love is patient, love is kind.
It does not envy, it does not boast, it is not proud. It does not dishonor others, it is not self-seeking, it is not easily angered, it keeps no record of wrongs.
Love does not delight in evil but rejoices with the truth.
It always protects, always trusts, always hopes, always perseveres."

Listen - look at him in the eye. I will find you, and count the sum of distance between each two different cff" as substrings of the message.
 

Input
An integer T (1T100), indicating there are T test cases.
Following T lines, each line contain an integer n (3n201314), as the identifier of message.
 

Output
The output contains exactly T lines.
Each line contains an integer equaling to:
i<j:sn[i..i+2]=sn[j..j+2]=cff"(j?i) mod 530600414,

where sn as a string corresponding to the n-th message.
 

Sample Input
9 5 6 7 8 113 1205 199312 199401 201314
 

Sample Output
Case #1: 5 Case #2: 16 Case #3: 88 Case #4: 352 Case #5: 318505405 Case #6: 391786781 Case #7: 133875314 Case #8: 83347132 Case #9: 16520782
 

Source
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:  5467 5466 5463 5462 5461 
 

递推公式。。。

首先有这么几个数组 

pre //首个c到之后c的距离和 

post //最后一个c到之前c的距离和

cnt //点数

ans //答案(任意两个c距离和)

f //最大两个c的间距

1 c

2 ff

3 cff

4 ffcff

5 cffffcff

6 ffcffcffffcff

7 cffffcffffcffcffffcff

这是前几项 很容易推出 

cnt[i] = cnt[i-2] + cnt[i-1] //点数

f[i] = f[i-2] + f[i-1] + ((i%2 == 0)? 3: 5) //c 最大间距

然后发现 如果有pre 跟post之后 ans也可推出

ans[i] = post[i-2]*cnt[i-1]+pre[i-1]*cnt[i-2]+x*cnt[i-2]*cnt[i-1]+ans[i-1]+ans[i-2]; // x :两串合并后中间cffffc f数量 跟当前串奇偶有关 x = ((i%2 == 0)? 3: 5)

ans = 前串末c到之前所有c的距离和 * 后串c个数 + 后串首c到之后所有c的距离和*前串c的个数 + 中间f数量*两串c数积 + 两串各自c距离和

原理: 组成新串后 后串任意c到前串每个c的距离等于 前串末c到之前每个c距离+生成新串中间新加f数*前串点数

前串c到后串同理 之后再加上两串各自c距离和即可

这样只需要再推出pre跟post即可

pre[i] = x*cnt[i-1]+pre[i-1]+pre[i-2]+f[i-2]*cnt[i-1] //新串首c到之后c的距离和 继承前后串距离和-pre[i-2,i-1] 然后到后串经过 cnt[i-1]*f[i-2] 和 x*cnt[i-1]

post[i] = x*cnt[i-2]+post[i-1]+post[i-2]+f[i-1]*cnt[i-2] //同上

递推结束 O(1)输出答案即可 注意推到过程中步步取余。。烦= =


代码如下:

#include <bits/stdc++.h>
#define mod 530600414
#define ll long long

using namespace std;

ll f[201316];
ll cnt[201316];
ll ans[201316],pre[201316],post[201316];

int main()
{
    int i,t,n,x;
    cnt[3] = 1;
    cnt[4] = 1;
    f[3] = 0;
    f[4] = 0;
    ans[3] = ans[4] = 0;
    pre[3] = pre[4] = post[3] = post[4] = 0;

    for(i = 5; i <= 201314; ++i)
    {
        cnt[i] = (cnt[i-1]+cnt[i-2])%mod;
<span style="white-space:pre">	</span>x = i&1? 5: 3;
        f[i] = (f[i-1]+f[i-2]+x)%mod;
        pre[i] = (((x*cnt[i-1]%mod+pre[i-1])%mod+pre[i-2])%mod+f[i-2]*cnt[i-1]%mod)%mod;
        post[i] = (((x*cnt[i-2]%mod+post[i-1])%mod+post[i-2])%mod+f[i-1]*cnt[i-2]%mod)%mod;
        ans[i] = (((post[i-2]*cnt[i-1]%mod+pre[i-1]*cnt[i-2]%mod)%mod+x*cnt[i-2]*cnt[i-1]%mod)%mod+ans[i-1]+ans[i-2])%mod;
    }

    scanf("%d",&t);
    for(int z = 1; z <= t; ++z)
    {
        scanf("%d",&n);
        printf("Case #%d: %I64d\n",z,ans[n]);
    }
    return 0;
}

【1012】 Largest Point (sort)

Largest Point

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1005    Accepted Submission(s): 397


Problem Description
Given the sequence A with n integers t1,t2,?,tn. Given the integral coefficients a and b. The fact that select two elements ti and tj of A and ij to maximize the value of at2i+btj, becomes the largest point.
 

Input
An positive integer T, indicating there are T test cases.
For each test case, the first line contains three integers corresponding to n (2n5×106), a (0|a|106) and b (0|b|106). The second line contains nintegers t1,t2,?,tn where 0|ti|106 for 1in.

The sum of n for all cases would not be larger than 5×106.
 

Output
The output contains exactly T lines.
For each test case, you should output the maximum value of at2i+btj.
 

Sample Input
2 3 2 1 1 2 3 5 -1 0 -3 -3 0 3 3
 

Sample Output
Case #1: 20 Case #2: 0
 

Source
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:  5467 5466 5463 5462 5461 
 

这题我做麻烦了 简单做法就是结构体 存放每个数的a*t1^2跟 b*t2 和这数下标

两数组排序后直接去第一个判断下标是否一样 一样就比较a取最大*b取次大跟a取次打b最大 输出最大即可

我做的是不断判断。。。

算是个教训 两种都贴上吧


代码如下:

//渣法。。四个判断。。。
#include <bits/stdc++.h>
#define ll long long
#define mx 2000000
#define fwrite() freopen("../out.out","r",stdout)
#define fread() freopen("../in.in","w",stdin)

using namespace std;

ll a,b;
vector <ll> v;

ll gt(ll t1,ll t2)
{
    return a*t1*t1+b*t2;
}

int main()
{
    //fread();
    //fwrite();
    int n,i,t,sz,z;
    vector<ll>::iterator it,tmp;
    ll t1,t2,x,ans;
    scanf("%d",&t);
    for(z = 1; z <= t; ++z)
    {
        v.clear();
        scanf("%d %I64d %I64d",&n,&a,&b);

        for(i = 0; i < n; ++i)
        {
            scanf("%I64d",&x);
            v.push_back(x);
        }
        sort(v.begin(),v.end());

        it = lower_bound(v.begin(),v.end(),0);
        sz = v.size();

        if(a < 0 && b < 0)//- -
        {
            tmp = it;
            tmp--;
            if(it == v.begin() || tmp == v.begin())
            {
                ans = max(gt(v[1],v[0]),gt(v[0],v[1]));
            }
            else ans = max(gt(*it,v[0]),gt(*tmp,v[0]));
        }
        else if(a < 0 && b >= 0)//- +
        {
            tmp = it;
            tmp++;
            if(tmp == v.end())
            {
                ans = max(gt(v[sz-1],v[sz-2]),gt(v[sz-2],v[sz-1]));
            }
            else if(it == v.begin())
            {
                ans = gt(v[0],v[sz-1]);
            }
            else
            {
                tmp = it--;
                ans = max(gt(*it,v[sz-1]),gt(*tmp,v[sz-1]));
            }
        }
        else if(a >= 0 && b <= 0)//+ -
        {
            ans = max(gt(v[0],v[1]),gt(v[sz-1],v[0]));
        }
        else//+ +
        {
            ans = gt(v[0],v[sz-1]);
            ans = max(ans,gt(v[sz-1],v[sz-2]));
            ans = max(ans,gt(v[sz-2],v[sz-1]));
        }
        printf("Case #%d: %I64d\n",z,ans);
    }
    return 0;
}


//排序输出。。。慢 慢又怎样 好想啊…………if渣法卡半天TOT
#include <bits/stdc++.h>
#define ll long long
#define mx 2000000
#define fwrite() freopen("../out.out","r",stdout)
#define fread() freopen("../in.in","w",stdin)

using namespace std;

struct Mult
{
    ll ans;
    int id;
    bool operator < (const struct Mult a)const
    {
        return ans == a.ans? id < a.id : ans > a.ans;
    }
};

Mult mla[6666666],mlb[6666666];
ll a,b;

int main()
{
    //fread();
    //fwrite();
    int n,i,t,z;
    ll x;
    scanf("%d",&t);
    for(z = 1; z <= t; ++z)
    {
        scanf("%d %I64d %I64d",&n,&a,&b);

        for(i = 0; i < n; ++i)
        {
            scanf("%I64d",&x);
            mla[i].ans = a*x*x;
            mlb[i].ans = b*x;
            mla[i].id = mlb[i].id = i;
        }
        sort(mla,mla+n);
        sort(mlb,mlb+n);
        printf("Case #%d: %I64d\n",z,mla[0].id != mlb[0].id? (mla[0].ans+mlb[0].ans): max(mla[0].ans+mlb[1].ans,mla[1].ans+mlb[0].ans));
    }
    return 0;
}





版权声明:本文为博主原创文章,未经博主允许不得转载。

【题解】 2015 ACM/ICPC Asia Regional Shenyang Online

原文:http://blog.csdn.net/challengerrumble/article/details/48706295

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!