Codeforces Round #241 (Div. 2) A B C题解

本文详细解析了Codeforces Round #241 (Div. 2) 中的A、B、C三道题目。A题是模拟猜数游戏,需要注意数的范围;B题涉及画家作画的顺序,通过动态规划或递推求解;C题为饭店请求与桌子分配问题,采用贪婪算法解决。每个题目都包含了解题思路和代码实现。
摘要由CSDN通过智能技术生成
题目链接http://codeforces.com/contest/416

 

 

 A 

题目大致描述根据所给条件猜数,最后输出任意一个符合条件的数。

 

思路模拟,设置一个头,一个尾,通过给定的条件不断更新头尾的大小,最后输出即可。

 

注意细节注意题中x,y的范围,- 109 ≤ x ≤ 109,- 2·109 ≤ y ≤ 2·109,在初始化头和尾的时候不要设置小了,我就在这个地方被hack了一次。

code:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#define SIZE 10
using namespace std;

int main()
{
    //分别记录三个不同的数据
    char c1[SIZE];
    char c2[SIZE];
    int N,n;
    int st=-2000000000,ed=2000000000;
    scanf("%d",&N);
    while(N--){
        //初始化数组的时候不要小了,不让在这个地方输入时会出现很奇怪的错误,'\0'是占一个位置的,我就在这里卡了好久,~~~~~~
        scanf("%s%d%s",c1,&n,c2);
        if((c1[0]=='>'&&c1[1]=='='&&c2[0]=='Y')||(c1[0]=='<'&&c1[1]=='\0'&&c2[0]=='N')){
            if(st<n) st=n;
        }
        else if((c1[0]=='<'&&c1[1]=='='&&c2[0]=='Y')||(c1[0]=='>'&&c1[1]=='\0'&&c2[0]=='N')){
            if(ed>n) ed=n;
        }
        else if((c1[0]=='>'&&c1[1]=='\0'&&c2[0]=='Y')||(c1[0]=='<'&&c1[1]=='='&&c2[0]=='N')){
            if(st<=n) st=n+1;
        }
        else if((c1[0]=='<'&&c1[1]=='\0'&&c2[0]=='Y')||(c1[0]=='>'&&c1[1]=='='&&c2[0]=='N')){
            if(ed>=n) ed=n-1;
        }
    }
    if(ed<st) printf("Impossible\n");
    else printf("%d\n",ed);
    return 0;
}


 B

题目描述:几位画家一起作画,每幅画必须由1~n画家一次处理过才算完成,每位画家必须在完成上一次画以后并且其前一位画家完成当前画之后才能处理当前画,问每幅画处理的时间。

 

思路:dp or 递推,在题目描述中已经强调了每位画家作画的前提,所以每位画家完成当前画所用的时间应该是由  完成上一幅画结束的时间  前一位画家完成当前画结束的时间  此画家完成当前画需要的时间 来控制的,所以可以得到状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i][j-1])+a[i][j]

 

code:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int Max_M=50005;
const int Max_N=10;

int dp[Max_M][Max_N],a[Max_M][Max_N];
int main()
{
    int m,n;
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]);
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            dp[i][j]=max(dp[i-1][j],dp[i][j-1])+a[i][j];
        }
        printf("%d",dp[i][n]);
        if(i!=m) printf(" ");
        else printf("\n");
    }
    return 0;
}

 

  c

题目描述:饭店有一系列的请求和几张桌子,问最大获利(省略了很多啊,具体看题目)

 

思路:greedy,对需求的获利按从大到小排列,获利相同时按人数从下到大排,然后对桌子大小从升序排列,枚举每个桌子带来的需求即可。为了满足输出的需要中间得设立一些标记变量。

细心~~~~

 

code:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int Max_M=1005;
const int Max_N=10;

struct Requst
{
    int c,p,flag;
}requst[Max_M];

struct Table
{
    int n,x,y;
} table[Max_M];

bool cmp(Requst a,Requst b)
{
    if(a.p==b.p) return a.c<b.c;
    return a.p>b.p;
}
bool cmp1(Table a,Table b)
{
    return a.n<b.n;
}
int main()
{
    int N,T,sum=0,n=0;
    scanf("%d",&N);
    for(int i=0;i<N;i++){
        scanf("%d%d",&requst[i].c,&requst[i].p);
        requst[i].flag=i+1;
    }
    scanf("%d",&T);
    for(int i=0;i<T;i++){
        scanf("%d",&table[i].n);
        table[i].x=i+1;
        table[i].y=0;
    }
    sort(requst,requst+N,cmp);
    sort(table,table+T,cmp1);
    for(int i=0;i<T;i++){
        for(int j=0;j<N;j++){
            if(requst[j].c<=table[i].n&&requst[j].flag!=-1){
                sum+=requst[j].p;
                table[i].y=requst[j].flag;
                requst[j].flag=-1;
                n++;
                break;
            }
        }
    }
    printf("%d %d\n",n,sum);
    for(int i=0;i<T;i++){
        if(table[i].y!=0)
            printf("%d %d\n",table[i].y,table[i].x);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值