ACM-BestCoder Round #32

来源:互联网 发布:携程首席数据官 编辑:程序博客网 时间:2024/06/06 02:26

A-PM2.5

题意:
先按两次数据之差由大到小排序,若差相等则按第二次数据由小到大排序,若第二次数据还相等则按城市数据的输入的先后顺序排序。
分析:
由于排序规则有多个,所以搞个结构体按照规则排序就ok了。但是需要注意的是,当数据相等时,排完序后的顺序不一定是输入顺序,所以按输入序号排序还是需要的。
源代码:
#include <cstdio>#include <algorithm>using namespace std;struct Data{    int first;    int second;    int id;    bool operator < (const Data &other) const    {        if(first-second           != other.first-other.second)        {            return first-second             > other.first-other.second;        }        if(second != other.second)        {            return second < other.second;        }        return id < other.id;    }}data[105];int main(){    int n;    while(~scanf("%d",&n))    {        for(int i=0; i<n; ++i)        {            scanf("%d%d",                  &data[i].first, &data[i].second);            data[i].id = i;        }        sort(data, data+n);        for(int i=0; i<n; ++i)        {            printf(i?" %d":"%d", data[i].id);        }        putchar('\n');    }    return 0;}

B-Negative and Positive (NP)

题意:问是否存在i、j,使得给出的k值等于那个关于i、j的表达式的值。
分析:如果直接枚举i、j,那么复杂度将是o(n^3);由于表达式是求和,所以想到可以先计算前缀和,那么复杂度是o(n^2);但是前面超时,所以考虑动态维护和,为了方便,假设sum[i]代后i项和(前缀和类似),那么如果要k = sum[i,j]成立的话,考虑奇偶,等价于k = sum[i]-sum[j]或k = -(sum[i]-sum[j])成立,因为a0为正或为负,然后从后往前枚举i,因为这样当在计算sum[i]时sum[j]是已经计算过了的,那么就只需查询sum[i]-k或sum[i]+k存在没,其实就是看有没有计算过的sum[j]和这次的sum[i]组合满足前面的等式,如果有则存在满足条件的i、j,否则继续枚举,同时将sum[i]保存,这样复杂度为o(n),至于保存数据的方法,要支持快速增加和查询元素,可以使用set或hash。
源代码:
1、使用set
#include <cstdio>#include <set>#define LL __int64#define MAX 10000100std::set <LL> st;int data[MAX];int n, k;// 快速输入void FaRead(int &x){    int f=1;    char ch=getchar();    x = 0;    while(ch<'0' || ch>'9')    {        if(ch=='-')        {            f  = -1;        }        ch = getchar();    }    while(ch>='0' && ch<='9')    {        x  = x*10 + ch - '0';        ch = getchar();    }    x *= f;}// c++ set集合实现int solve(){    st.clear();    LL sum = 0;    st.insert(0);    for(int i=n, t=1; i>=1; --i, t^=1)    {        // 注意奇、偶,后缀和将是+-+-+或-+-+-的形式        if(t)        {            sum += data[i];            if (st.find(sum-k) != st.end())            {                return 1;            }        }        else        {            sum -= data[i];            if(st.find(k+sum) != st.end())            {                return 1;            }         }        st.insert(sum);    }    return 0;}int main (){    int t, cas=0;    scanf("%d", &t);    while(t--)    {        FaRead(n);        FaRead(k);        for(int i=1; i<=n; ++i)        {            FaRead(data[i]);        }        printf("Case #%d: %s\n", ++cas,               solve()?"Yes.":"No.");    }}
2、使用hash表
#include <cstdio>#include <cstring>#define LL __int64#define MAX 10000100const LL MOD = 1000007;int data[MAX];int n, k;// 哈希表实现struct HashTable{    struct Edge    {        LL num;        int next;    };    Edge edge[2*MAX];    int countedge;    int head[MOD+100];    void init()    {        memset(head, -1, sizeof(head));        countedge = 0;    }    void insert(LL num)    {        int start = num%MOD;        edge[countedge].next = head[start];        edge[countedge].num  = num;        head[start] = countedge;        countedge++;    }    int find(LL num)    {        int start = num%MOD;        int ind;        for(ind=head[start]; ind!=-1; ind=edge[ind].next)        {            if(edge[ind].num == num)            {                break;            }        }        return ind;    }}HT;// 快速输入void FaRead(int &x){    int f=1;    char ch=getchar();    x = 0;    while(ch<'0' || ch>'9')    {        if(ch == '-')        {            f  = -1;        }        ch = getchar();    }    while(ch>='0' && ch<='9')    {        x  = x*10 + ch - '0';        ch = getchar();    }    x *= f;}// c++ set集合实现int solve(){    HT.init();    LL sum = 0;    HT.insert(0);    for(int i=n, t=1; i>=1; --i, t^=1)    {        // 注意奇、偶,后缀和将是+-+-+或-+-+-的形式        if(t)        {            sum += data[i];            if (HT.find(sum-k) != -1)            {                return 1;            }        }        else        {            sum -= data[i];            if(HT.find(k+sum) != -1)            {                return 1;            }         }        HT.insert(sum);    }    return 0;}int main(){    int t, cas=0;    scanf("%d", &t);    while(t--)    {        FaRead(n);        FaRead(k);        for(int i=1; i<=n; ++i)        {            FaRead(data[i]);        }        printf("Case #%d: %s\n", ++cas,               solve()?"Yes.":"No.");    }}




0 0
原创粉丝点击