ACM训练日记—12月17日

来源:互联网 发布:提比略知乎 编辑:程序博客网 时间:2024/05/21 17:45

        最近打的两场cf真郁闷,上了2分,下了2分。实在是太菜了,一直只能做出来3道水题。有基本功不扎实的原因,写道水题费时间太长了,读题目的速度有待提高,第四题往往都是来不及做就结束了。

下面整理一下这两场吧。

Codeforces Round #451 (Div. 2)

       A题(Rounding):就是给一个数,四舍五入,大水题,不说了。

       B题(Proper Nutrition):x*a + y*b = n,就是给出n,a,b。求出是否有满足条件的x,y,输出YES or NO,和其中一组x,y,这道题卡了一下,第一反应扩展欧几里得算法,然而我高估这道题了,一看数据范围,就是暴力枚举所有x,y做就可以。。。水题

      C题:(Phone Numbers):题目解释起来有点麻烦,直接看代码吧。其实就是暴力。。。

做完这道题,时间基本快没了。。。实在是太菜了QAQ

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define LL long long
using namespace std;
struct node
{
    string name;//记录名字
    vector<string>num;//该名字下的多个号码
};
vector<node>str;
int judge(string a,string b)//判断b字符串是不是a字符串末尾部分
{
    int len=b.length();
    int e=a.length();
    int flag=0;
    for(int i=0;i<len;i++)
    {
        if(a[e-len+i]!=b[i])
        {
            flag=1;
            break;
        }
    }
    if(flag) return 0;
    else return 1;
}
int main()
{
    int n,k;
    cin>>n;
    string h;
    for(int i=1;i<=n;i++)
    {
        int flag=-1;
        cin>>h;
        for(int i=0;i<str.size();i++)//暴力找是否已经记录过此人
        {
            if(h==str[i].name)
            {
                flag=i;//确定操作人的位置
                break;
            }
        }
        if(flag==-1)//没有这个人,建立账户,放入名字,记录位置
        {
            node u;
            u.name=h;
            str.push_back(u);
            flag=str.size()-1;
        }
        cin>>k;
        for(int j=1;j<=k;j++)
        {
            string r;
            cin>>r;
            int ww=0;
            for(int q=0;q<str[flag].num.size();q++)//依次找此位置下的人,有没有满足条件的号码
            {
                string c,t;
                c=str[flag].num[q];
                if(c.length()>=r.length())//比较,分类讨论新输入号码长度与原有长短的不同情况
                {
                   int aa;
                   aa=judge(c,r);
                   if(aa) {ww=1;break;}
                }
                else
                {
                    int aa;
                    aa=judge(r,c);
                    if(aa){str[flag].num[q]=r;ww=1;break;}
                }
            }
            if(ww==0) str[flag].num.push_back(r);
        }
    }
    cout<<str.size()<<endl;//输出
    for(int i=0;i<str.size();i++)
    {
        cout<<str[i].name<<" "<<str[i].num.size()<<" ";
        for(int j=0;j<str[i].num.size();j++)
        {
            cout<<str[i].num[j]<<" ";
        }
        cout<<endl;
    }
}

        D题,我还得在补一下,感觉可以用单调队列做一下。


Codeforces Round #452 (Div. 2)

        A题(Splitting in Teams):就是给一些数(1或2),求互相搭配可以出来多少个3。水题。。

        B题(Months and Years):就是给出若干个数,求是否为月份里的一部分。

因为n<=24,所以直接暴力。。纯暴力

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define LL long long
using namespace std;
int mou[200]={0,31,28,31,30,31,30,31,31,30,31,30,31,
                31,28,31,30,31,30,31,31,30,31,30,31,
                31,29,31,30,31,30,31,31,30,31,30,31,
                31,28,31,30,31,30,31,31,30,31,30,31,
                31,28,31,30,31,30,31,31,30,31,30,31};
int a[30],n;
int solve(int k)//找以k为首的mou[],对比a[],是否符合。
{
    int flag=0;
    for(int i=0;i<n;i++)
    {
        if(mou[k+i]!=a[i])
        {
            flag=1;
            break;
        }
    }
    if(flag==0) return 1;
    else return 0;
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    int e=0;
    for(int i=1;i<=37;i++)
    {
        if(solve(i))
        {
            e=1;
            break;
        }
    }
    if(e) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}

        C题(Dividing the numbers):给出一个数n,找1,2,,,n,中分两组,两组分别的和相差最小,输出。

其实无论n是哪个正数,ans不是1,就是0。

看代码吧。。很简单的规律。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
int vis[60005];
int main()
{
    memset(vis,0,sizeof(vis));
    ll n;
    ll r;
    ll a,b;
    cin>>n;
    r=n;
    a=n*(n+1)/2;//先全部放一组,然后依次向另一边哪。。
    b=0;
    ll cnt=0;
    while(1)
    {
        ll k;
        k=(a-b)/2;
        if(k>=n)//
        {
            vis[n]=1;
            a=a-n;
            b=b+n;
            n--;
        }
        else
        {
            a=a-k;
            b=b+k;
            vis[k]=1;
            break;
        }
    }
    ll ans;
    ans=abs(a-b);
    cout<<ans<<endl;
    for(int i=1;i<=r;i++)
    {
       if(vis[i]) {cnt++;}
    }
    cout<<cnt<<" ";
    for(int i=1;i<=r;i++)
    {
        if(vis[i]) cout<<i<<" ";
    }
    cout<<endl;
}