11.3 morning

noip模拟题day1

总览(Overview)

 

题目名称

取模

等比数列

回文串

程序名

mod

sequence

palindromes

输入文件名

mod.in

sequence.in

palindromes.in

输出文件名

mod.out

sequence.out

palindromes.out

时间限制

1s

1s

2s

空间限制

128M

128M

128M

题目类型

传统题

传统题

传统题

取模(mod)

【题目描述】

有一个整数a和n个整数b_1, …, b_n。在这些数中选出若干个数并重新排列,得到c_1,…, c_r。我们想保证a mod c_1 mod c_2 mod … mod c_r=0。请你得出最小的r,也就是最少要选择多少个数字。如果无解,请输出-1.

【输入说明】

输入文件的第一行有一个正整数T,表示数据组数。

接下去有T组数据,每组数据的第一行有两个正整数n和a.

第二行有n个正整数b_1, …, b_n.

【输出说明】

一行,输出答案。

【样例输入】

2

2 9

2 7

2 9

6 7

【样例输出】

2

-1

【数据范围】

对于40%的数据,n<=8

对于100%的数据,T<=5,n<=20,1 <=a <=10^6,b_i<=10^6

暴力

#include<cstdio>
#include<algorithm>
#define inf 1e9
#define maxn 25
using namespace std;
int T,n,x,a[maxn],falg,ans;
int init(){
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
int cmp(int x,int y){
    return x>y;
}
int Min(int x,int y){
    return x<y?x:y;
}
void Dfs(int now,int num,int s){
    if(num>=ans)return;
    if(s==0){
        ans=Min(ans,num);return;
    }
    if(now==n+1)return;
    if(s>=a[now])Dfs(now+1,num+1,s%a[now]);
    Dfs(now+1,num,s);
}
int main()
{
    freopen("mod.in","r",stdin);
    freopen("mod.out","w",stdout);
    T=init();
    while(T--){
        n=init();x=init();
        ans=inf;falg=0;
        a[0]=0;int c;
        for(int i=1;i<=n;i++){
            c=init();
            if(c<=x)a[++a[0]]=c;
            if(c==1)falg=1;
        }
        n=a[0];if(x==0)falg=0;
        if(falg){
            printf("1
");continue;
        }
        sort(a+1,a+1+n,cmp);
        Dfs(1,0,x);
        if(ans==inf)printf("-1
");
        else printf("%d
",ans);
    }
    fclose(stdin);fclose(stdout);
    return 0;
}
View Code

等比数列(sequence)

【题目描述】

判断一个数列是否为等比数列。

等比数列的定义为能被表示成a,aq,aq^2,aq^3...的数列,其中a和q不等于0。

【输入说明】

输入文件的第一行有一个正整数T,表示数据组数。

接下去有T组数据,每组数据的第一行一个整数n,接下来第二行n个数非负整数Ai,表示数列。

【输出说明】

对于每一个组的每个数据输出单独一行Yes或者No。

【样例输入】

2

3

1 1 1

3

1 4 2

【样例输出】

Yes

No

【数据范围】

对于40%的数据 0<=Ai<=10^9

对于100%的数据 T<=5,n<=1000,0<=Ai<=10^100

/*读题读题 首项公比不为0 */
#include<cstdio>
#include<cstring>
#define maxn 1010
using namespace std;
int T,n,A[maxn][110],a[maxn],b[maxn];
char s[maxn];
int init(){
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
void Mul(int a[maxn],int b[maxn],int c[maxn]){
    for(int i=1;i<=a[0];i++){
        for(int j=1;j<=b[0];j++){
            c[i+j-1]+=a[i]*b[j];
            if(c[i+j-1]>9){
                c[i+j]+=c[i+j-1]/10;
                c[i+j-1]%=10;
            }
        }
        int p=b[0]+i-1;
        while(c[p+1]){
            p++;c[p+1]+=c[p]/10;c[p]%=10;
        }
    }
    for(int i=a[0]+b[0];i>=1;i--)
        if(c[i]){
            c[0]=i;break;
        }
}
bool Cmp(){
    if(a[0]!=b[0])return 0;
    for(int i=1;i<=a[0];i++)
        if(a[i]!=b[i])return 0;
    return 1;
}
int main()
{
    freopen("sequence.in","r",stdin);
    freopen("sequence.out","w",stdout);
    T=init();
    while(T--){
        memset(A,0,sizeof(A));
        n=init();int falg=0;
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            A[i][0]=strlen(s);
            for(int j=1;j<=A[i][0];j++)
                A[i][j]=s[A[i][0]-j]-'0';
        }
        if(A[1][0]==1&&A[1][1]==0)falg=1;
        else if(A[2][0]==1&&A[2][1]==0)falg=1;
        else for(int i=2;i<n;i++){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            Mul(A[i-1],A[i+1],a);
            Mul(A[i],A[i],b);
            if(!Cmp()){
                falg=1;break;
            }
        }
        if(falg)printf("No
");
        else printf("Yes
");
    }
    fclose(stdin);fclose(stdout);
    return 0;
}
View Code

回文串(palindromes)

【题目描述】

判断是否能将字符串S分成三段非空回文串。

【输入说明】

第一行一个整数T,表示数据组数。

对于每一个组,仅包含一个由小写字母组成的串。

【输出说明】

对于每一组,单行输出"Yes" 或 "No"。

【样例输入】

2

abc

abaadada

【样例输出】

Yes

No

【数据范围】

对于40%的数据,|S|<=100

对于60%的数据,|S|<=1000

对于100%的数据,T<=20,|S|<=20000

乱搞80

/*hash+类似离散化的思想 80 已弃疗2333 */
#include<cstdio>
#include<cstring>
#define maxn 20010
#define P 29
#define ll long long
using namespace std;
ll T,n,A[maxn],B[maxn],a[maxn],b[maxn],p[maxn],falg;
char s[maxn];
void Get(){
    p[0]=1;
    for(int i=1;i<=20000;i++)
        p[i]=p[i-1]*P;
}
void Hash1(){
    A[0]=0;
    for(int i=1;i<=n;i++)
        A[i]=A[i-1]*P+s[i];
}
void Hash2(){
    B[0]=0;
    for(int i=1;i<=n;i++)
        B[i]=B[i-1]*P+s[n-i+1];
}
ll Query1(int l,int r){
    return A[r]-A[l-1]*p[r-l+1];
}
ll Query2(int l,int r){
    return B[r]-B[l-1]*p[r-l+1];
}
int main()
{
    freopen("palindromes.in","r",stdin);
    freopen("palindromes.out","w",stdout);
    scanf("%d",&T);Get();
    while(T--){
        scanf("%s",s+1);
        n=strlen(s+1);
        a[0]=0;b[0]=0;
        Hash1();Hash2();falg=0;
        for(int i=1;i<=n;i++){
            ll x=Query1(1,i);
            ll y=Query2(n-i+1,n);
            if(x==y)a[++a[0]]=i;
        }
        for(int i=n;i>=1;i--){
            ll x=Query1(i,n);
            ll y=Query2(1,n-i+1);
            if(x==y)b[++b[0]]=i;
        }
        for(int i=1;i<=a[0];i++){
            for(int j=1;j<=b[0];j++){
                if(a[i]+1>b[j]-1)break;
                ll x=Query1(a[i]+1,b[j]-1);
                ll y=Query2(n-b[j]+2,n-a[i]);
                if(x==y){
                    falg=1;break;
                }
            }
            if(falg)break;
        }
        if(falg)printf("Yes
");
        else printf("No
");
    }
    fclose(stdin);fclose(stdout);
    return 0;
}
View Code

正解你猜

原文地址:https://www.cnblogs.com/yanlifneg/p/6039621.html