Contest

来源:互联网 发布:两年程序员转行做什么 编辑:程序博客网 时间:2024/05/16 14:39

点击:http://oj.acm.zstu.edu.cn/JudgeOnline/contest.php?cid=3650

Problem A: 回文

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 1637  Solved: 505

Description

小王想知道一个字符串是否为ABA’型字符串。ABA’型字符串的定义:S=ABA’ABA’都是原字符串的子串(不能是空串),A’的意思是A的反转串,B不一定要和AA’不同。符合ABA’型的例如:"aba”"acbbca”"abcefgcba”等。"Abcefgcba”ABA’型,因为它能找到一组对应的A"abc”)B(”efg”)A’("cba")满足定义。

Input

第一行给测试总数T(T <= 1000),接下来有T组测试数据。
每组测试数据有一行字符串S(1 <= |S| <= 50000),字符串保证只有小写或大写英文字母。

Output

每组测试数据输出一行,如果SABA’型字符串,输出"YES”,否则输出"NO"

Sample Input

5abAggCodeforcesacmermcamyacm

Sample Output

NONONOYESYES
题解:字符串

WA了三遍的水题。字符串处理,把题读全了就可以了。我是分的奇偶长度,分别考虑的,这样清晰点

#include <iostream>#include <bits/stdc++.h>using namespace std;char s[600050];int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%s",s);        int len=strlen(s);        if(len==1)        {            printf("NO\n");            continue;        }        int i,j;        if(len%2==0)        {            i=0;            j=len-1;            while(i<j)            {                if(s[i]==s[j])                {                    i++;                    j--;                }                else break;            }            if(s[0]==s[len-1]&&len>2)            {                printf("YES\n");            }            else printf("NO\n");        }        else        {            i=0;            j=len-1;            while(i<j)            {                if(s[i]==s[j])                {                    i++;                    j--;                }                else break;            }            if(s[0]==s[len-1])            {                printf("YES\n");            }            else printf("NO\n");        }    }    return 0;}



Problem I: 约素

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 1809  Solved: 469

Description

判断一个正整数n的约数个数是否为p,其中p是素数。

Input

第一行给测试总数T(T <= 10000)。

接下来有T行,每行有两个数字n(1 <= n <= 1000000000)和p(2 < p <= 1000000000)。

Output

每组测试数据输出一行,如果n的约数个数是p,输出“YES”,否则输出“NO”。

Sample Input

5
64 7
911 233
1080 13
1024 11
20170211 1913

Sample Output

YES
NO
NO
YES
NO

题解:暴力求约数,常规技巧简化

约数,我都想问到底什么叫做约数。以前做的计算约数的个数的理解记得不是这样的来。这个题的约数就是让你暴力找一遍n%i==0时i的个数。而紫书上的约数的个数是表示质因子的个数相乘得来的。

当然这个也不能1-n暴力,因为对于n%x==0的话,也就得出了另一个约数:y=n/x,既然是约数,x,y都是小于n的,那么x从1开始一直到,n/x就可以了,此时当x增大的时候,n/x就在减小。知道x>=n/x.特别处理,当x==n/x的时候约数的个数+1,否则+2(x和n/x都是n的约数)

#include<bits/stdc++.h>using namespace std;int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n,p;        int sum;        scanf("%d%d",&n,&p);        sum=0;        for(int i=1;i<=n/i;i++)        {            if(n%i==0)            {                sum++;                if(i!=n/i)sum++;            }        }        if(n==1)sum=1;        //cout<<sum<<endl;       if(sum==p)printf("YES\n");       else printf("NO\n");    }    return 0;}



Problem D: 买iphone

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 1719  Solved: 316

Description

自从上次仓鼠中了1000万彩票后,彻底变成了土豪了,一群人愿意认他做干爹,仓鼠决定送他的干儿子每人一部iphone。仓鼠今天带了一群人去买iphone,每个人身上都背着一个大背包,只有3种背包,分别能装a,b,c个iphone,仓鼠希望每个人都能用iphone装满自己的背包。仓鼠有n个干儿子,也就是要买n部手机,仓鼠带了k个人去买手机,问是否存在一种情况能让每个买iphone的人的背包都装满

Input

输入包含多组测试数据,每组一行,包含5个整数n, k, a, b, c
(1 <= n, k , a, b, c <= 10000)
abc可以相同

Output

如果存在输出Yes,否则输出No

Sample Input

10 3 3 3 420 7 1 1 180 3 100 3 315 4 3 5 6

Sample Output

YesNoNoYes

HINT

样例一3个人分别带大小为 3 3 4的背包去买手机正好每个人都装满

样例二 很明显只有一种背包,全部都是1也无法买20部iphone

样例四 4个人分别带大小为 3 3 3 6的背包去买手机正好每个人都装满
题解:暴力

没想到这个题纯暴力就能过了,当然了不是k^2级别的。一共有k个人去装手机,假设有x个人装a,y(y小于k-x)个人装b,剩下的人装c,只要判断出x*a+y*b+(k-x-y)*c==n的情况就可以了

#include<bits/stdc++.h>using namespace std;int main(){    int n,k,a,b,c;    while(~scanf("%d%d%d%d%d",&n,&k,&a,&b,&c))    {        int flag=0;        for(int i=0;i<=k;i++)        {            for(int j=0;j<=k-i;j++)            {                if(a*i+b*j+c*(k-i-j)==n)                {                    flag=1;                    break;                }                if(flag)break;            }        }        if(flag)printf("Yes\n");        else printf("No\n");    }    return 0;}


Problem E: 同源数

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 1288  Solved: 224

Description

如果x和y的质因子集合完全相同,那么我们就说他们是同源的。
比如说18 = 2 * 32,12 = 3 * 22

Input

本题有多组数据(组数 <= 555555)。
每组数据输入形如:
x y
x, y为整数(1 <= x, y <= 1e18)

Output

输出形入:
ans
如果x, y为同源数,那么ans为”Yes”, 不然为”No”.

Sample Input

18 122 3

Sample Output

YesNo
题解:数论,唯一分解定理,gcd(),

这个题是分析的时间最长的一个题了,最后想出解法后还因为没考虑到全面的情况,又花了很长的时间。首先读完题目的第一反应就是唯一分解定理,然后就卡壳了。突然想到了gcd(),就在纸上分析了一下,慢慢的才ac的。

同源数,也就是他们的质因子的元素是相同的(个数不一定相同)。假如a=2*3*3*5*7,b=2*2*3*5*5*7,他们两个是同源数,对a,b求gcd(a,b)=g;显然g分解后质因子一定包含他们共有的质因子,即2*3*5*7,然后a,b都除以他们的质因子,如果两个数是同源数的话,那么让a一直除以a和g的gcd(),a=a/gcd(a,g),直到a==1或gcd(g,a)为止,如果a==1的说说明了a的质因子只包含了和g相同的质因子,如果a!=1&&gcd(a,g)==1的话,说明a和g互素,也就是a中的质因子有和g中的质因子不同的元素。同理对b也这样处理。如果a==1&&b==1的话说明是同源数,否则不是。

特殊处理a==b和a==1||b==1的情况。

#include<bits/stdc++.h>using namespace std;unsigned long long gcd(unsigned long long a,unsigned long long b){    return b==0?a:gcd(b,a%b);}int main(){    unsigned long long x,y;    while(~scanf("%lld%lld",&x,&y))    {        if(x==y)        {            printf("Yes\n");        }        else if(x==1&&y!=1)        {            printf("No\n");        }        else if(x!=1&&y==1)        {            printf("No\n");        }        else        {            unsigned long long z=gcd(x,y);            unsigned long long a,b;            a=x/z;            b=y/z;            //cout<<z<<" "<<a<<" "<<b<<endl;            int aa,bb;            aa=1;            bb=1;            while(1)            {                unsigned long long q;                q=gcd(a,z);                a=a/q;                if(a==1)                {                    break;                }                if(q==1)                {                    aa=0;///不行                    break;                }            }            while(1)            {                unsigned long long q;                q=gcd(b,z);                b=b/q;                if(b==1)                {                    break;                }                if(q==1)                {                    bb=0;///不行                    break;                }            }            if(aa&&bb)            {                printf("Yes\n");            }            else printf("No\n");        }    }    return 0;}



Problem H: 玩具

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 718  Solved: 132

Description

商店有n个玩具,第i个玩具有价格a[i]和快乐值b[i]。有一天,小王来到商店想买一些玩具,商店老板告诉他,如果他买的所有玩具的位置是连续的,那么老板答应小王购买的所有玩具中某一个可以免费。小王接受老板的提议,他现在有零花钱k可以用来买玩具,那么他能获得的最大的快乐值是多少。

Input

第一行给测试总数T(T <= 100),接下来有T组测试数据。
每组测试数据第一行有两个数字n(1 <= n <= 5000)k(0 <= k <= 1000000000)
第二行有n个数字,第i个数字表示第i个玩具的价格a[i](1 <= a[i] <= 1000000)
第三行有n个数字,第i个数字表示第i个玩具的快乐值b[i](1 <= b[i] <= 1000000)

Output

每组测试输出小王能获得的最大快乐值。

Sample Input

35 141 2 3 4 55 4 3 2 13 1100 1000 10000100 1000 100001 010000001000000

Sample Output

15100001000000
题解:前缀和,RMQ,取尺法

当读完这个题的时候想到的是0,1背包的变形,但是包太大了,就不在想了。

后来用的线段树的查询,但是超时了,后来补题的时候想到了前i个数的和,那么s[i]-s[j]及时区间i~j的和了,在用RMQ求区间最大值,此时还是用的n^2的区间判断还是超时了。最后用的取尺法来确定一个区间,因为如果大区间合法的话,那么小区间就不用判断了,这样会节省时间。但是在开始的时候把自己RMQ的区间和前缀和的区间弄混了,卡了好久。

#include <bits/stdc++.h>using namespace std;int a[5005],b[5005];int p[5005],happy[5005];int M[5005*4];void build(int node,int b,int e,int M[],int a[]){    if(b==e)M[node]=a[b];    else    {        build(2*node,b,(b+e)/2,M,a);        build(2*node+1,(b+e)/2+1,e,M,a);        if(M[node*2]>=M[2*node+1])M[node]=M[2*node];        else M[node]=M[2*node+1];    }}int query(int node,int b,int e,int M[],int i,int j){    int p1,p2;    if(i>e||j<b)return 0;    if(b>=i&&e<=j)return M[node];    p1=query(2*node,b,(b+e)/2,M,i,j);    p2=query(2*node+1,(b+e)/2+1,e,M,i,j);    if(p1==0)return p2;    if(p2==0)return p1;    if(p1>=p2)return p1;    return p2;}int main(){    int t,n,K;    scanf("%d",&t);    while(t--)    {        int mx=0;        scanf("%d%d",&n,&K);        p[0]=0;        for(int i=1; i<=n; i++)        {            scanf("%d",&a[i]);            p[i]=p[i-1]+a[i];        }        build(1,1,n,M,a);        happy[0]=0;        for(int j=1; j<=n; j++)        {            scanf("%d",&b[j]);            happy[j]=happy[j-1]+b[j];        }        int l,r;        l=1;///不能设为0,因为我的rmq查询的区间最大值是从l->r的全部值,        ///而我的p和happy所包含的p[r]-p[l]是从l+1->r的值        r=1;        while(r<=n)        {            if((p[r]-p[l]+a[l]-query(1,1,n,M,l,r))<=K)            {                //cout<<l<<" "<<r<<" "<<query(1,1,n,M,l,r)<<endl;                mx=max(mx,happy[r]-happy[l]+b[l]);                r++;            }            else            {                while(l<r&&(p[r]-p[l]+a[l]-query(1,1,n,M,l,r))>K)                {                    //cout<<l<<" "<<r<<" "<<query(1,1,n,M,l,r)<<endl;                    l++;                    //mx=max(mx,happy[r]-happy[l]);                }                if((p[r]-p[l]+a[l]-query(1,1,n,M,l,r))<=K)mx=max(mx,happy[r]-happy[l]+b[l]);                if(r==n)break;            }        }        printf("%d\n",mx);    }    return 0;}


1 0
原创粉丝点击