模拟赛1103d1

取模(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<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 10000000
using namespace std;
int T,x,n,ans;
int a[110];
int init()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
void dfs(int w,int t,int now)
{
    if(t>=ans)return;
    if(now==0){ans=t;return;}
    if(w==n+1)return;
    dfs(w+1,t,now);
    dfs(w+1,t+1,now%a[w]);
}
int cmp(int a,int b)
{
    return a>b;
}
int main()
{
    freopen("mod.in","r",stdin);
    freopen("mod.out","w",stdout);
    T=init();
    while(T--)
    {
        n=init();x=init();
        for(int i=1;i<=n;i++)
          a[i]=init();
        sort(a+1,a+n+1,cmp);
        ans=inf;
        dfs(1,0,x);
        if(ans==inf) printf("-1
");
        else printf("%d
",ans);
    }
    fclose(stdin);fclose(stdout);
    return 0;
}

 

                                                                                                     等比数列(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

/*利用等比中项+高精乘法判断*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1010
#define M 310
using namespace std;
int T,n;
int t[M],r[M];
int a[N][M];
char s[M];
int init()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
void mul(int c[M],int a[M],int b[M])
{
    int l1=a[0],l2=b[0];
    for(int i=1;i<=l1;i++)
    {
        int x=0;
        for(int j=1;j<=l2;j++)
        {
            c[i+j-1]+=a[i]*b[j]+x;
            x=c[i+j-1]/10;
            c[i+j-1]%=10;
        }
        c[i+l2]+=x;
    }
    c[0]=l1+l2;
    while(c[0]>1&&c[c[0]]==0)c[0]--;
}
int judge(int a[M],int b[M])
{
    int l1=a[0],l2=b[0];
    if(l1!=l2)return 0;
    for(int i=1;i<=l1;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--)
    {
        n=init();
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            int l=strlen(s);a[i][0]=l;
            for(int j=1;j<=l;j++)
              a[i][j]=s[l-j]-'0';
        }
        if(a[1][0]==1&&a[1][1]==0)
        {
            printf("No
");
            continue;
        }
        if(n==1)
        {
            printf("Yes
");
            continue;
        }
        if(a[2][0]==1&&a[2][1]==0)
        {
            printf("No
");
            continue;
        }
        if(n==2)
        {
            printf("Yes
");
            continue;
        }
        int flag=0;
        for(int i=3;i<=n;i++)
        {
            memset(t,0,sizeof(t));
            mul(t,a[i-2],a[i]);
            memset(r,0,sizeof(r));
            mul(r,a[i-1],a[i-1]);
            if(judge(t,r))continue;
            flag=1;break;
        }
        if(flag)
        {
            printf("No
");
            continue;
        }
        printf("Yes
");
    }
    fclose(stdin);fclose(stdout);
    return 0;
}

回文串(palindromes)

【题目描述】

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

【输入说明】

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

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

【输出说明】

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

【样例输入】

2

abc

abaadada

【样例输出】

Yes

No

【数据范围】

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

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

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

原文地址:https://www.cnblogs.com/harden/p/6039741.html