BestCoder Round #58 (div.2)(hdu 5494,hdu5495,hdu5496)

Card Game

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5494

解题思路:

由于都是随机出牌, Soda要必胜显然是他的最小的mm张牌的和要大于Beta最大的mm张牌的和.

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

int a[505],b[505];

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i = 0; i < n; i++)
            scanf("%d",&a[i]);
        for(int i = 0; i < n; i++)
            scanf("%d",&b[i]);
        sort(a,a+n);
        sort(b,b+n);
        int ans1 = 0,ans2 =  0;
        for(int i = 0; i < m; i++)
            ans1 += a[i];
        for(int i = n-1; i >= n-m; i--)
           ans2 += b[i];
        //cout<<ans2<<endl;
        if(ans1 > ans2)
            puts("YES");
        else
            puts("NO");
    }
    return 0;
}


LCS

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5495

解题思路:

题目中给出的是两个排列, 于是我们我们可以先把排列分成若干个环, 显然环与环之间是独立的. 事实上对于一个长度为l (l > 1)l(l>1)的环, 

我们总可以得到一个长度为l-1l1的LCS, 于是这个题的答案就很明显了, 就是nn减去长度大于11的环的数目.

AC代码:

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

const int N = 100005;
int a[N],b[N],c[N];
bool vis[N];

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        for(int i = 1; i <= n; i++){
            scanf("%d",&b[i]);
            c[a[i]] = b[i];
        }
        memset(vis,0,sizeof(vis));
        int ans = 0,tmp,x;
        for(int i = 1; i <= n; i++){
            x = c[i];
            if(vis[x])
                continue;
            tmp = 0;
            while(!vis[x]){
                vis[x] = 1;
                tmp++;
                x = c[x];
            }
            ans += tmp > 1;
        }
        printf("%d\n",n - ans);
    }
    return 0;
}


Beauty of Sequence

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5496

解题思路:

考虑每个数字对最终答案的贡献. 对于每个数, 我们只算它出现在连续相同元素的第一个时的贡献, 这样会使计算简便很多. 假设这个

数是a[i]a[i], 那么i后面的随便选有2^{n-i}2ni种. 考虑a[i]a[i]前面的数, 要么一个不选, 要么选择的最后一个数和a[i]a[i]不同, 然后就可以算出来了.

AC代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
const int N = 1e5+5;
map<int,int>m;

int n,a[N];
ll p[N],f[N];

void solve(){
    ll sum = 0,ans = 0;
    scanf("%d",&n);
    for(int i = 1; i <= n; i++){
        scanf("%d",&a[i]);
        sum = (sum+a[i]) % MOD;
    }

    ans = sum*p[n-1] % MOD;
    m.clear();
    for(int i = 1; i <= n; i++){
        if(!m[a[i]]){
            f[i] = 0;
            m[a[i]] = i;
        }
        else{
            int j = m[a[i]];
            f[i] = (f[j]+p[j-1])%MOD;
            m[a[i]] = i;
        }
    }
    //for(int i = 1; i <= n; i++)cout<< f[i]<< " ";cout<<endl;
    for(int i = 1; i <= n; i++){
        ll t = f[i]*p[n-i] % MOD * a[i] % MOD;
        ans = (ans-t+MOD) % MOD;
    }
    printf("%d\n",ans);
}
int main(){
    p[0] = 1;
    for(int i = 1; i < N; i++)
        p[i]=(p[i-1]<<1) % MOD;
    int T;
    scanf("%d",&T);
    while (T--)
        solve();
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值