Codeforces Round #260 (Div. 2)

第一题:Laptops

题意:Dima 和 Alex 在争论笔记本的价格和质量的关系。Dima认为笔记本的价格越高,笔记本的质量也越好。Alex认为一定有两台笔记本,第一台的价格严格低于第二台的,但是第一台的质量严格好于第二台。现在给你一组数据(1<=ai,bi<=n,ai和bi分别唯一) ,分别代表第i台笔记本的价格和质量,问这组数据能否证明Alex的说法。

题解:读入ai和bi后,依ai从小到大排序,如果bi不是依次递增,即存在Alex提及的情况。

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
#define INF 0x6fffffff
struct node
{
    int a,b;
} num[100005];
bool cmp(const struct node &a,const struct node &b)
{
    return a.a<b.a;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; ++i)
    {
        scanf("%d%d",&num[i].a,&num[i].b);
    }
    if(n==1)
    {
        printf("Poor Alex\n");
        return 0;
    }
    sort(num,num+n,cmp);
    bool flag=true;
    for(int i=0; i<n; ++i)
    {
        if(num[i].b!=i+1)
        {
            printf("Happy Alex\n");
            flag=false;
            break;
        }
    }
    if(flag)
        printf("Poor Alex\n");
    return 0;
}

第二题:Fedya and Maths

题意:(1n + 2n + 3n + 4nmod 5的值,n可能非常大

题解:根据模运算规则,(a+b)%p=(a%p+b%p)%p   (a*b)%p=(a%p*b%p)%p ,会发现该算式的值是4 0 0 0的循环,因此问题就转化为判断n是否是4的倍数,而判断是否是4的倍数可以通过计算最后两位是否能被4整除得出(或者直接使用java中的大数类)   

代码:

import java.io.BufferedInputStream;
import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String[]args){
        BigInteger n;
        BigInteger f=new BigInteger("4");
        Scanner cin = new Scanner (new BufferedInputStream(System.in));
        n=cin.nextBigInteger();
        if(n.mod(f).equals(new BigInteger("0"))){
            System.out.println("4");
        }
        else{
            System.out.println("0");
        }
    }
}

第三题:Boredom

题意:Alex 创造了一个游戏。给一串数字(1 ≤ ai ≤ 105),玩家可以走很多步,每步删除一个元素ak(只删除一个),同时删除数字串中所有等于ak-1和ak+1的元素,玩家在这步中得到ak分。问在给定的数字串中最大可以得多少分。

题解:动态规划。dp[i][0]代表不选取数字i,dp[i][1]代表选择数字i。

           转移方程: dp[i][0]=max(dp[i-1][0],dp[i-1][1])//不选数字i,所以数字i-1可选可不选

                           dp[i][1]=dp[i-1][0]+num[i]*i//选数字i的状态只能是从不选数字i-1传递过来的

           由于数据范围比较大,最好采用__int64定义变量

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
#define INF 0x6fffffff
#define N 100005
#define max(a,b) (a)>(b)?(a):(b)
__int64 num[N];
__int64 dp[N][2];
int main()
{
    int n,a,maxx=0;
    memset(dp,0,sizeof(dp));
    scanf("%d",&n);
    for(int i=0;i<n;++i)
    {
        scanf("%d",&a);
        maxx=max(maxx,a);
        ++num[a];
    }
    for(int i=1;i<=maxx;++i)
    {
        dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
        dp[i][1]=dp[i-1][0]+num[i]*i;
    }
    printf("%I64d\n",max(dp[maxx][0],dp[maxx][1]));
    return 0;
}



来源:http://blog.csdn.net/acm_ted/article/details/38454865

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值