码迷,mamicode.com
首页 > 其他好文 > 详细

[BestCoder] Round #11

时间:2015-02-08 18:12:29      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

1001

http://acm.hdu.edu.cn/showproblem.php?pid=5054

输出Yes只有一种情况.

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <cmath>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#define rd(x) scanf("%d",&x)
#define rd2(x,y)  scanf("%d%d",&x,&y)
#define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int dx[8]={0,0,-1,1,1,1,-1,-1};
int dy[8]={1,-1,0,0,-1,1,-1,1};
//关键点是中点吧
int n,m,x,y;


int main()
{
    while(cin>>n>>m>>x>>y)
    {
        if(2*x==n&&2*y==m)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
    return 0;
}


1002

http://acm.hdu.edu.cn/showproblem.php?pid=5055

给出n个数字(每个数字0~9),用这n个数字组成一个数,要求不能有前导0,且最后一位必须是奇数。不能组成则输出-1.

可以构造出数的情况有: 只有一个数,且该数是奇数;n个数中大于0的数至少有2个,且n个数中存在奇数。

如果能满足的话,那么最小的奇数做数的最后一位,剩下的数从大到小排在前面就是所求的数。

写的时候逻辑有点乱.....这类题写的时候一定得考虑全面一些。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <cmath>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#define rd(x) scanf("%d",&x)
#define rd2(x,y)  scanf("%d%d",&x,&y)
#define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int dx[8]={0,0,-1,1,1,1,-1,-1};
int dy[8]={1,-1,0,0,-1,1,-1,1};
const int maxn=102;
int num[maxn];
bool hasodd;
int minodd;
int n;

bool cmp(int a,int b)
{
    return a>b;
}

int main()
{
    while(rd(n)!=EOF)
    {
        hasodd=0;
        minodd=100;//最小的奇数
        int p=-1;//最小的奇数的位置
        int cnt=0;//大于0的数字有多少个
        for(int i=1;i<=n;i++)
        {
            rd(num[i]);
            if(num[i]>0)
                cnt++;
            if(num[i]&1)
            {
                hasodd=1;
                if(minodd>num[i])
                   {
                       minodd=num[i];
                       p=i;
                   }

            }
        }
        if(n==1)
        {   if(hasodd)
            cout<<num[1]<<endl;
            else
                cout<<-1<<endl;
            continue;
        }
        if(cnt>=2&&hasodd)
        {
            swap(num[p],num[n]);
            sort(num+1,num+n,cmp);
            for(int i=1;i<=n;i++)
                cout<<num[i];
            cout<<endl;
        }
        else
            cout<<-1<<endl;
    }
    return 0;
}

1003

http://acm.hdu.edu.cn/showproblem.php?pid=5056

给出一个只有小写字母组成的字符串,然后给出一个数字k,问有多少子串满足  该子串中相同字母出现的次数不超过k。比如有一个子串 abac k=2的话,a的次数=2不超过k,b,c的次数均为1,也不超过k,所以这个子串就是符合要求的.

一个长度为n的字符串,子串一共有n(n+1)/2个,题目中n是100000,直接枚举肯定不行。

一开始想的也是枚举,枚举每个位置,判断以该位置开头的子串有多少个,两重循环,第二重循环就是长度了,一开始以为长度最多就是26(26个字母),复杂度还可以,但是忘了k的事...k不一定等于1啊,有可能很大....所以悲剧了,果断超时..

看到解题报告是 也是枚举每个位置,统计的则是以该位置为结尾的最大子串的长度,则是以该位置结尾的所有子串的个数,这个好理解,比如k=2,   bcca,当位置为a时,满足条件的最大子串为 bcca,长度为4,那么满足的所有子串的个数也为4,分别为  bcca  cca  ca  a。开辟两个指针,一个是枚举的位置,一个是满足该位置的最大串的起始位置,处治为该串的第一个位置。map<char,int>mp,记录每个字母出现的次数.下面以具体例子来说明是怎么工作的吧,解释不清楚.....

比如串   abbcbcc  k=2

一开始位置为1, ‘a‘,起始指针start为1,mp[‘a‘]++,  该值满足<=k,ans+=     i-start+1  ;即ans+=1,对应的串为a

后来位置为2,‘b‘,    起始指针start为1, mp[‘b‘]++,  满足条件,   ans+= 2-start+1;       即ans+=2,对应的串为  b     ab

后来位置为3,也满足条件,ans+=3,对应的串为  b  bb  abb

后来位置为4, 也满足条件,ans+=4;对应的串为 c bc bbc abbc

后来位置为5, mp[‘b‘]++,这时候mp[b]=3,  3>k,不符合条件,原因是b这个字母多了一个,要想以该位置为结尾,那么就得从前面去掉一个b,要求最大串,所以去掉最前面的一个b,同时更新起始位置, 这时候起始位置还是1,要想符合条件,就得移动该指针,mp[‘a‘]--,这是起始指针start对应的位置,start++, 这时候start=2,对应的字母为b,找到第一个b了,要把它去掉,所以再执行一次 mp[‘b‘]--,start++, 这时候start=3, 符合题意了, 满足的最大串为 bcb,   ans+= 5-start+1,即ans+=3 ,对应的子串为  b   cb   bcb

后来同理....

从上面流程中可以看出start指针是一直往前的,这个效率比前面说的那个要高,有些位置满足的子串数可以0(1)来计算出

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <cmath>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#define rd(x) scanf("%d",&x)
#define rd2(x,y)  scanf("%d%d",&x,&y)
#define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int dx[8]={0,0,-1,1,1,1,-1,-1};
int dy[8]={1,-1,0,0,-1,1,-1,1};
char s[100004];
map<char,int>mp;
int len;
int k;
ll ans;
int main()
{
    int t;rd(t);
    while(t--)
    {
        mp.clear();
        scanf("%s",s+1);
        rd(k);
        len=strlen(s+1);
        int start=1;
        ans=0;
        for(int i=1;i<=len;i++)
        {
            mp[s[i]]++;
            if(mp[s[i]]>k)
            {
                while(s[start]!=s[i])
                {
                    mp[s[start]]--;
                    start++;
                }
                mp[s[start]]--;
                start++;
            }
            ans+=i-start+1;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


 

 

 

 

[BestCoder] Round #11

标签:

原文地址:http://blog.csdn.net/sr_19930829/article/details/43638667

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!