2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest

Link


A

题意

给出n(1<=n<=100)人的积分,让n人去参加2到5人的比赛,每次比赛参赛人会减少一分,问怎么安排比赛让n个人分数一样,且分数最高,比赛次数不限定

分析

ym:2~5,可以看做2~3,因为4和5可以拆成2~3,实质上需要奇数个人组队的只有一种情况:1,2,2,2,这种情况下必须要奇数,其余都可以每次消2个,模拟有点难写啊

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 100+7;
const ll mod = 998244353;

int ans[maxn*maxn][maxn],n,a[maxn];
pair<int,int>b[maxn];


int main()
{
    scanf("%d", &n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d", &a[i]);
        b[i]={a[i],i};
    }
    int cnt=0;
    while(1)
    {
        sort(b+1,b+n+1);
        if(b[1].first==b[n].first) break;
        ++cnt;
        int num=0;
        for(int i=1;i<=n;i++)
        {
            if(b[i].first > b[1].first)
                num++;
        }
        if(num>=2 && num<=5 && b[n].first-1==b[1].first)
        {
            for(int i=n;i>=n-num+1;i--)
            {
                b[i].first--;
                ans[cnt][b[i].second]=1;
            }
        }
        else
        {
            b[n].first--;
            ans[cnt][b[n].second]=1;
            if(b[n-1].first>0)
            {
                b[n-1].first--;
            }
            ans[cnt][b[n-1].second]=1;
        }
    }
    printf("%d\n%d\n", b[1].first,cnt);
    for(int i=1;i<=cnt;i++)
    {
        for(int j=1;j<=n;j++)
            cout<<ans[i][j];
        cout<<endl;
    }
    return 0;
}

B 

题意

给出数组长度,和最多ceil(1.5×n)-2个比较运算符(可以是大于小于等于),得到最大值与最小值所在下标

分析

czh:第一次遇到交互题,与以前的题目不一样,这题不能在输入完再统一输出答案,而要根据输入来一步一步地输出

ym:暴力的比较次数为2*n,考虑归并排序的思想,可以先把n/2个大的放在一下,n/2个小的放在一下,然后再分别在各自里面找即可,交互题每次输出后 fflush(stdout)

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

int QA(int x,int y)
{
    printf("? %d %d\n",x,y);
    fflush(stdout);
    char c='0';
    while(c!='>' && c!='=' && c!='<')c=getchar();
    if(c=='>')return 1;
    if(c=='=')return 0;
    if(c=='<')return -1;
    return 1000;
}


int t,n;
char c;
vector<int>ma,mi;

int main()
{
    scanf("%d", &t);
    while(t--)
    {
        ma.clear();
        mi.clear();
        scanf("%d", &n);
        for(int i=1;i<=n-1;i+=2)
        {
            int k=QA(i,i+1);
            if(k>=0)
            {
                ma.push_back(i);
                mi.push_back(i+1);
            }
            else
            {
                ma.push_back(i+1);
                mi.push_back(i);
            }
        }
        if(n&1) ma.push_back(n), mi.push_back(n);
        bool flag=true;
        int maxx=ma[0];
        int minx=mi[0];
        for(int i=1; i<int(ma.size()); i++)
        {
            int k=QA(ma[i],maxx);
            if(k>0)
                maxx=ma[i];
        }
        for(int i=1; i<int(mi.size()); i++)
        {
            int k=QA(mi[i],minx);
            if(k<0)
                minx=mi[i];
        }
        printf("! %d %d\n", minx,maxx);
        fflush(stdout);
    }
    return 0;
}

C

题意

给出n个城市,m条边,w个商店,每个商店所属的城市,商品数量,商品单价,q个询问,每次询问给g城市送r个商品在总价不超过a的条件下最小时间,从一个城市到相邻城市所需时间为1

分析

二分答案,bfs检查所有可以到达的商店,贪心check即可,自己写了每次把所有商店拿出来然后排序,TLE了

正确姿势:先把所有商店按单价排序,对于每次询问,直接bfs,然后对可以到达的商店直接从下到大取即可

Trick:每个城市可能有多个商店!!!


D

题意

有n座桥,前一座的终点是下一座的起点,有一种药,它可以使原来的速度从0.5变为1,持续时间为r,而且两次药使用时间一定要大于等于r,,每座桥有一个长度和一个限制时间(多少时间之内要通过这座桥),问最少使用多少次药通过所有的桥. 

分析


E

题意

给你一组分数,以及解锁后该分数的改变大小.问怎样改变解锁分数的顺序,能够使得过程中所有人排名的变化量最大. 

分析


F

题意

分析


G

题意

给出n个修车的需求,用开始时间与持续时间来描述,让你安排修车日程,满足以下规则

1.如果在开始时间到结束时间是空闲的,那么就在这段时间修这辆车

2.如果不是空闲,那么寻找一个最早结束的,且期间为空闲的时间修这辆车

分析

czh:将那些可以插入的区间拿出来,初始是1到无穷可以插入,插入后就变成1到s[1]-1,和t[1]+1到无穷

如果不能插入,就给这些区间排序,找到第一个可以插入的区间


H

题意

给出n个a字符串,m个b字符串,让你找出一个字符串它满足以下条件

1.与所有的a字符串匹配

2.与所有的b字符串不匹配

匹配需要满足以下条件

1.长度相同

2.每个字符相同,其中?可以代替所有字符

如果找不到则打印No 

分析

czh:先遍历所有的a数组,找到一个ans,再用ans遍历b数组,如果ans与某个b数组匹配则No


I

题意

有n个数,每个数有两个属性,给你两个序列,从第一个序列中取s个数,相加记为sum1,第二个序列中取q个数,但是两个序列中的数的位置不能够相同,相加记为sum2,求sum1+sum2的最大值. 

分析


J

题意

给出n个瓶子的容量和其内水的体积。问你怎样倒水使含水的瓶子个数最少,每次倒水可以倒一体积到另一个里面,保证个数最少时倒水所花的最少时间(次数)

分析

ym:这数据范围就写着dp两个字啊!!!赛时没有想出怎么定义dp状态


K

题意

分析

 


L

题意

分析


Summary

Ym:有点崩盘啊

czh:

猜你喜欢

转载自www.cnblogs.com/Deadline/p/9233304.html