2016百度之星资格赛1001-1004

来源:互联网 发布:综合网络弱电系统图 编辑:程序博客网 时间:2024/05/29 10:10

不加头文件了。。看着乱

1001:

逆元的应用
求出第一个字符到后面每个字符的哈希值,存储到数组ansss[]中
求出第一个字符到后面每个字符哈希值的逆元的乘积,存储在数组ansss1[]中

如果求[i,j]这一段哈希值, 只要输出 ansss[j]*ansss1[i-1]即可。

#define RI(N) scanf("%d",&(N))#define RII(N,M) scanf("%d %d",&(N),&(M))#define RIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))#define mem(a) memset((a),0,sizeof(a))using namespace std;const int inf=1e9;const int inf1=-1*1e9;double EPS=1e-10;long long inv(long long a,long long m){    if(a == 1)return 1;    return inv(m%a,m)*(m-m/a)%m;}int main(){    int n;    while(RI(n)!=EOF)    {        char s[100005];        int ansss[100005];        int ansss1[100005];        ansss[0]=1;        ansss1[0]=1;        scanf("%s",s);        int m=strlen(s);        for(int i=0; i<m; i++)        {            ansss[i+1]=ansss[i]*(s[i]-28)%9973;            ansss1[i+1]=ansss1[i]*inv(s[i]-28,9973)%9973;        }        for(int i=0; i<n; i++)        {            int a,b;            RII(a,b);            printf("%d\n",ansss[b]*ansss1[a-1]%9973);        }    }    return 0;}

1002

根据排列组合
假设以C(n,i)表示

结果为C(n,0)+C(n-1,1)+C(n-2,2)+C(n-3,3) 一直到 C(n-i,i)(其中i*2=n或者i*2+1=n停止)

因为数比较大所以选用java

import java.math.BigInteger;import java.util.Scanner;public class Main {    public static BigInteger cc(BigInteger n, BigInteger x) {        if(n.equals(x) ) return BigInteger.ONE;        BigInteger ex = BigInteger.ONE;        BigInteger tt=x.add(BigInteger.ONE);        while (!tt.equals(n.add(BigInteger.ONE))) {            ex = ex.multiply(tt);            tt=tt.add(BigInteger.ONE);        }        BigInteger end = (n.subtract(x));        BigInteger need = BigInteger.ONE;        BigInteger ans=need;        while (!need.equals(end.add(BigInteger.ONE))) {            ans= ans.multiply(need);            need=need.add(BigInteger.ONE);        }        return ex.divide(ans);    }    public static void main(String[] args) {        Scanner cin = new Scanner(System.in);        while (cin.hasNext()) {            BigInteger n;            n = cin.nextBigInteger();            BigInteger ans;            ans = BigInteger.ONE;            for (BigInteger i = BigInteger.ONE; ; i=i.add(BigInteger.ONE)) {                if(n.subtract(i).equals(BigInteger.ZERO)) break;                ans = ans.add(cc(n.subtract(i), i));                if(n.subtract(i.add(i)).equals(BigInteger.ONE)) break;                if(n.subtract(i.add(i)).equals(BigInteger.ZERO)) break;            }            System.out.println(ans);        }    }}

1003

直接用字典树就可以了 ,注意删除的值可能不存在,同时删除一个前缀时要减的次数是这个前缀上的字母出现的最小的次数

#define RI(N) scanf("%d",&(N))#define RII(N,M) scanf("%d %d",&(N),&(M))#define RIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))#define mem(a) memset((a),0,sizeof(a))using namespace std;const int inf=1e9;const int inf1=-1*1e9;double EPS=1e-10;typedef long long LL;struct node{    int countt;    struct node *next[26];    node()    {        countt=1;        mem(next);    }};struct node *root;void insertt(char *s){    int i=0;    struct node *p;    p=root;    while(s[i])    {        if(p->next[s[i]-'a'])        {            p=p->next[s[i]-'a'];            p->countt++;        }        else        {            p->next[s[i]-'a']=new node();            p=p->next[s[i]-'a'];           // cout<<p->countt<<endl;        }        i++;    }};bool findd(char *s){    int i=0;    struct node *p;    p=root;    while(s[i])    {        if(!p->next[s[i]-'a']) return false;        else{            p=p->next[s[i]-'a'];            if(p->countt<=0) return false;        }        i++;    }    return true;}void deletee(char *s){    int i=0;    struct node *p;    p=root;    int maxx=inf;    while(s[i])    {        if(p->next[s[i]-'a'])        {            p=p->next[s[i]-'a'];           maxx=min(maxx,p->countt);        }        else return ;        i++;    }    i=0;    p=root;    while(s[i])    {        if(p->next[s[i]-'a'])        {            p=p->next[s[i]-'a'];            p->countt-=maxx;        }        i++;    }    mem(p->next);}int main(){    root=new node();    int n;    RI(n);    for(int i=0;i<n;i++)    {        char que[15];        char word[35];        scanf("%s",que);        scanf("%s",word);        if(que[0]=='i')        {            insertt(word);        }        if(que[0]=='s')        {            if(findd(word)) printf("Yes\n");            else printf("No\n");        }        if(que[0]=='d')        {            deletee(word);        }    }    return 0;}

1004

将名字排序并map一下就可以了

#define RI(N) scanf("%d",&(N))#define RII(N,M) scanf("%d %d",&(N),&(M))#define RIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))#define mem(a) memset((a),0,sizeof(a))using namespace std;const int inf=1e9;const int inf1=-1*1e9;double EPS=1e-10;map<string,int> mapp;long long inv(long long a,long long m){    if(a == 1)return 1;    return inv(m%a,m)*(m-m/a)%m;}int main(){    int n;    RI(n);    for(int i=0;i<n;i++)    {char s[50];        scanf("%s",s);        int m=strlen(s);        sort(s,s+m);        printf("%d\n",mapp[s]++);    }    return 0;}
0 0
原创粉丝点击