ACM ICPC 2017 Warmup Contest 7(CTU Open Contest 2016)

14 篇文章 0 订阅
13 篇文章 0 订阅

ccsp与区域赛都越来越近了,模拟与区域赛题并进,还有一堆作业,有点累,想玩耍,感觉自己有点迷失,算了,还是就这样吧,努力向前


练习赛7,打两个签到题走人,继续刷csp去


B. Hot Air Ballooning

思路:统计不同人用过的气球的方案数,又是个去重问题,又想往set上放,后来发现气球数很少,完全可以数组统计,而气球总组合有限,虽然不大,但强搜可能会感觉tle,加个状压好了,感觉现在自己特别喜欢做状压的题,特别得心应手

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 1010;

bool situation[maxn];
bool temp[10];
char temps[maxn];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int sum = 0;
        memset(situation,false,sizeof(situation));
        while(n--)
        {
            scanf("%s",temps);
            memset(temp,false,sizeof(temp));
            int len = strlen(temps);
            for(int i=0;i<len;i++)
            {
                    temp[temps[i]-'0'] = true;
            }
            int now = 0;
            for(int pos=1;pos<=9;pos++)
            {
                if(temp[pos])
                {
                    now |= (1<<(pos-1));
                }
            }
            //cout << now << " * " << endl;
            if(situation[now]==false)
            {
                situation[now] = true;
                sum++;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

J. Colorful Tribune

思路:不过这次的签到题似乎有点过于水了,n行n列n类数每类n个,每行每列不重,有一个特殊元素,找出并复原

这要分两种情况,一个是特殊元素为新加入的元素,二是特殊元素为已有元素,第二种情况相对比较负责,需要重新定位,最后还是一点小细节吧

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 100;

char tribune[maxn][maxn];
int num[maxn];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        bool one = false;
        memset(num,0,sizeof(num));
        for(int i=0;i<n;i++)
        {
            scanf("%s",tribune[i]);
            for(int j=0;j<n;j++)
            {
                num[tribune[i][j]-'A']++;
            }
        }
        char wrong,correct;
        for(int i=0;i<26;i++)
        {
            if(num[i]==1)
            {
                wrong = i + 'A';
                one = true;
            }
            else if(num[i] == n+1)
            {
                wrong = i + 'A';
            }
            else if(num[i] == n-1)
            {
                correct = i + 'A';
            }
        }
        //cout << wrong << endl;
        if(one)
        {
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    if(tribune[i][j]==wrong)
                    {
                        printf("%d %d %c\n",i+1,j+1,correct);
                    }
                }
            }
        }
        else
        {
            int line[maxn];
            int row[maxn];
            memset(line,0,sizeof(line));
            memset(row,0,sizeof(row));
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    if(tribune[i][j]==wrong)
                    {
                        line[i]++;
                        row[j]++;
                    }
                }
            }
            int rel,rer;
            for(int i=0;i<n;i++)
            {
                if(line[i]>1)
                {
                    rel = i+1;
                }
                if(row[i]>1)
                {
                    rer = i+1;
                }
                //cout << line[i] << "*" << row[i]<< endl;
            }
            printf("%d %d %c\n",rel,rer,correct);
        }
    }
    return 0;
}

/*
6
OEYCDK
EYOKCD
KDCEOY
CKHOYE
YOEDKC
DCKYEO
3
IWL
GIW
WLI
6
OEYCDK
EYOKCD
KDCEOY
CKKOYE
YOEDKC
DCKYEO
*/

好了,继续回去刷csp了


补完一道csp的T3大模拟后,还是觉得补一道icpc的题换换吧


 I. Suspicious Samples

思路:其实这题的难度不大,但通过这题,对于set的插入、删除和排序又有了新的认识,确实收获不少

set中cmp的编写

这个确实是一个非常关键的地方,第一是书写格式,第二就是一定要确定对于所有满足的情况全部都true;

由于set去、具有去重性,所以一点点小小的疏忽就会导致部分值部莫名其妙地去掉了


struct cmp
{
    bool operator()(Pattern a,Pattern b)const
    {
        if((a.value>b.value)||(a.value==b.value&&a.time<b.time))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
};

还有就是earse了,这是一个大坑点啊

1.earse完后会导致迭代器失效,所以一定要注意及时重新对迭代器赋值(这题没遇到这个坑点,但确实是常见而又易错的坑点)

2.earse和find结合时,要注意find返回值为末尾时(为找到),千万要特判,不可随意earse

3.一旦set中的元素被earse完后,所有begin(),end()及类似迭代器全部失效,这个算是今天最大的坑点了吧

if(pattern.find(tempdelete)!=pattern.end())
{
       pattern.erase(pattern.find(tempdelete));
}
if(pattern.empty())
{
       now = 0;
}
else
{
       ……
}

还有就是界限退出条件的判断这些了吧


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
#include <set>

using namespace std;

const int maxn = 1e5+10;

int t[maxn];
int v[maxn];

typedef struct PATTERN
{
    int time;
    int value;
}Pattern;

struct cmp
{
    bool operator()(Pattern a,Pattern b)const
    {
        if((a.value>b.value)||(a.value==b.value&&a.time<b.time))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
};

set<Pattern,cmp> pattern;

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        t[0] = -1e9;
        v[0] = 0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&t[i],&v[i]);
        }
        int c;
        scanf("%d",&c);
        while(c--)
        {
            pattern.clear();
            int re = 0;
            char r[10],f[10];
            int l;
            scanf("%s%s%d",r,f,&l);
            int pos,st=1;
            int sum = 0;
            int num = 0;
            for(pos=2;pos<=n;pos++)
            {
                //cout << pos << "*" <<st<< endl;
                sum += v[pos-1];
                num++;
                //cout << pos << "#" << st << endl;
                //set<Pattern> :: iterator it;
                Pattern temp;
                temp.value = v[pos-1];
                temp.time = t[pos-1];
                pattern.insert(temp);
                /*cout << pos << "#" << st <<"#" << t[pos-1]<< endl;
                for(it=pattern.begin();it!=pattern.end();it++)
                {
                    cout << (it->time) << " ";
                }
                cout <<endl;*/
                while(t[pos]-t[st]>l&&st<pos)
                {
                    //cout << pos << "#" << st << endl;
                    sum -= v[st];
                    num--;
                    Pattern tempdelete;
                    tempdelete.value = v[st];
                    tempdelete.time = t[st];
                    //cout << "^" <<pattern.size()<<"^"<<((pattern.find(tempdelete))->time)<< endl;
                    if(pattern.find(tempdelete)!=pattern.end())
                    {
                        /*if(pattern.size()==1)
                        {
                            pattern.clear();
                        }
                        else
                        {*/
                            pattern.erase(pattern.find(tempdelete));
                        //}
                    }
                    //cout << "^^" << endl;
                    /*cout << pos << "^" << st <<"^" << t[st]<< endl;
                    for(it=pattern.begin();it!=pattern.end();it++)
                    {
                        cout << (it->time) << " ";
                    }
                    cout <<endl;*/
                    st++;
                }
                //cout << "&&" << endl;
                long long now;
                if(pattern.empty())
                {
                    now = 0;
                }
                else
                {
                    if(strcmp(f,"max")==0)
                    {
                        now = (long long)((pattern.begin())->value) * (long long)(num);
                    }
                    else if(strcmp(f,"min")==0)
                    {
                        now = (long long)((pattern.rbegin())->value) * (long long)(num);
                    }
                    else
                    {
                        now = (long long)(sum);
                    }
                }
                if(strcmp(r,"gt")==0&&((long long)(v[pos])*(long long)(num)>now))
                {
                    re++;
                }
                else if(strcmp(r,"lt")==0&&((long long)(v[pos])*(long long)(num)<now))
                {
                    re++;
                }
            }
            printf("%d\n",re);
        }
    }
    return 0;
}

文章地址:http://blog.csdn.net/owen_q/article/details/78234317

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值