2016 百度之星资格赛题解(hdu 5685,5686,5687,5688,5689)

此次的百度之星资格赛,题目都比较好理解,就不再给出了。以下是AC的代码,可能存在bug,欢迎大家debug

Problem A
[http://acm.hdu.edu.cn/showproblem.php?pid=5685]
化简过后的题意就是求一段序列中的区间乘,由于询问次数比较多,直接求乘可能会超时,所以想到前缀乘的想法。preMulit[i]表示前i个序列的前缀乘。若要求[l,r]区间内的的数字全乘起来,那么用preMulit[r]/preMulit[l-1]即可,考虑到取模的问题,用到逆元。

#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <cstdio>
#define MaxSize 100000+100
const int mod = 9973;
using namespace std;
char str[MaxSize];
long long PreMulti[MaxSize];

long long pow_m(long long x,long long n)
{
    long long res = 1;
    while(n>0)
    {
        if(n&1) res = res*x%mod;
        x = x*x %mod;
        n>>=1;
    }
    return res;
}
long long inv(long long a)
{
    return pow_m(a,mod-2);
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        scanf(" %s",str);
        int len = strlen(str);
        PreMulti[0] = 1;
        for(int i=0;i<len;i++){
            PreMulti[i+1] = (PreMulti[i]*((int)str[i]-28))%mod;
        }
        int a,b;
        while(n--){
            scanf("%d%d",&a,&b);
            if(a>b){int tmp = a; a=b; b=tmp;}
            printf("%I64d\n",(PreMulti[b]*inv(PreMulti[a-1]))%mod);
        }
    }
    return 0;
}

Problem B
http://acm.hdu.edu.cn/showproblem.php?pid=5686
当前个数与其上一个和上上个的个数相关,所以考虑斐波那契数列,用到大数,不想敲C++模板,所以用了java

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        int n;
        BigInteger [] fun = new BigInteger[201];
        fun[1]=fun[0] = new BigInteger("1");
        for(int i=2;i<=200;i++){
            fun[i] = fun[i-1].add(fun[i-2]);
        }
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext())
        {
            n = cin.nextInt();
            System.out.println(fun[n]);
        }
    }
}

Problem C
http://acm.hdu.edu.cn/showproblem.php?pid=5687
字典树,很明显。不过要考虑一个问题(当时我没考虑到),比如先插入abc,abd,再删除以abc及为开始的串,再查ab的时候,应该输出No, ab这个单词本来并不存在。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

struct node{
    node *child[26];
    bool isExist;
    node(){
        for(int i=0;i<26;i++){
            child[i] = NULL;
        }
        isExist = false;
    }
}*root;
void Insert(char cmp[],node* root)
{
    node *now = root;
    int len = strlen(cmp);
    for(int i=0;i<len;i++){
        now->isExist = true;
        if(now->child[cmp[i]-'a']==NULL)
            now->child[cmp[i]-'a']=new node;
        now=now->child[cmp[i]-'a'];
    }
    now->isExist = true;
}
void Delete(char cmp[],node* root)
{
    node *now = root;
    int len = strlen(cmp);
    for(int i=0;i<len;i++){
        int cnt =0;
        for(int j=0;j<26;j++){
            if(now->child[j]!=NULL){
                cnt++;
            }
        }
        if(cnt <=1){
            now->isExist = false;
            for(int j=0;j<26;j++){
                if(now->child[j]!=NULL)
                    now->child[j]=NULL;
            }
            return ;
        }
        now=now->child[cmp[i]-'a'];
    }
    now -> isExist = false;
    for(int i=0;i<26;i++){
        if(now->child[i]!=NULL)
            now->child[i]=NULL;
    }
}
bool Search(char cmp[],node* root)
{
    node *now = root;
    bool flag = true;
    int len = strlen(cmp);
    for(int i=0;i<len;i++){
        if(now->child[cmp[i]-'a']==NULL||now->child[cmp[i]-'a']->isExist == false){
            flag = false;break;
        }
        now=now->child[cmp[i]-'a'];
    }
    return flag;
}
void TireClear(node* now){
    for(int i=0;i<26;i++){
        if(now->child[i]!=NULL) TireClear(now->child[i]);
    }
    delete now;
}
char ope[10],str[35];
int main()
{
    int N;
    scanf("%d",&N);
    root = new node;
    while(N--)
    {
        scanf(" %s%s",ope,str);
        if('i'==ope[0]){
            Insert(str,root);
        }
        else if('d'==ope[0]){
            if(Search(str,root))
                Delete(str,root);
        }
        else if('s'==ope[0]){
            if(Search(str,root))
                printf("Yes\n");
            else
                printf("No\n");
        }

    }
    TireClear(root);
    return 0;
}

Problem D
用map映射,很简单想到
http://acm.hdu.edu.cn/showproblem.php?pid=5688

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>

using namespace std;
const int INF=0x3f3f3f3f;
char s[100005];
int N;
map<string,int> MP;
string now;
int main()
{
    while(scanf("%d",&N)!=EOF)
    {
        for(int i=0;i<N;i++)
        {
            cin>>now;
            sort(now.begin(),now.end());
            printf("%d\n",MP[now]);
            MP[now]++;
        }
    }

    return 0;
}

Problem E
http://acm.hdu.edu.cn/showproblem.php?pid=5689
一道模拟题,求当前式子与前面的式子是否矛盾,当输入的是复合句子的时候,对自身检查是否矛盾,如果是那么这个句子以后也就不需要检查了,否则对前面所有的句子进行检查,依次输出。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cctype>
#include <map>
#define MaxSize 1000+10
using namespace std;
//每个简单条件
struct formula{
    string name,ope;
    int number;
};
//每个复合条件
struct node{
    int id;
    int fcnt;
    bool isRight; //复合式子本身是否合法
    formula f[500];
    node(){fcnt = 0;isRight = true;}
}Each[MaxSize];

//判断交集
bool Judge(formula x,formula y){
    if(x.name != y.name)
        return true;
    bool ok = true;
    if(x.ope=="==")
    {
        if(y.ope=="=="&&y.number!=x.number){ok = false;}
        else if(y.ope==">"&&y.number>=x.number){ok = false;}
        else if(y.ope==">="&&y.number>x.number){ok = false;}
        else if(y.ope=="<"&&y.number<=x.number){ok = false;}
        else if(y.ope=="<="&&y.number<x.number){ok = false;}
    }
    else if(x.ope==">")
    {
        if(y.ope=="=="&&y.number<=x.number){ok = false;}
        //3 <x <4 is not ok
        else if(y.ope=="<"&&y.number<=x.number+1){ok = false;}
        else if(y.ope=="<="&&y.number<=x.number){ok = false;}
    }
    else if(x.ope==">=")
    {
        if(y.ope=="=="&&y.number<x.number){ok = false;}
        //3 <x <4 is not ok
        else if(y.ope=="<"&&y.number<=x.number){ok = false;}
        else if(y.ope=="<="&&y.number<x.number){ok = false;}
    }
    else if(x.ope=="<")
    {
        if(y.ope=="=="&&y.number>=x.number){ok = false;}
        else if(y.ope==">"&&y.number>=x.number-1){ok = false;}
        else if(y.ope==">="&&y.number>=x.number){ok = false;}
    }
    else if(x.ope=="<=")
    {
        if(y.ope=="=="&&y.number>x.number){ok = false;}
        else if(y.ope==">"&&y.number>=x.number){ok = false;}
        else if(y.ope==">="&&y.number>x.number){ok = false;}
    }
    return ok;

}
int main()
{
    int N;
    scanf("%d",&N);
    int allcnt = 0;
    int idcnt = 0;
    while(N--){
        Each[allcnt].id = ++idcnt;
        string str;

        scanf("\n");
        getline(cin,str);

        int len = str.length();
        string tope="";
        string tname="";
        int number = 0;
        //number < 0;
        bool isS = false;
        //模拟出每行输入的简单式子
        for(int i=0;i<len;i++){
            if(isalpha(str[i])){
                tname += str[i];
            }
            else if(isdigit(str[i])){
                number = (number*10)+(str[i]-'0');
            }
            else if(str[i]=='>'||str[i]=='<'||str[i]=='='){
                tope += str[i];
            }
            //负数
            else if(str[i]=='-'){
                isS = true;
            }
            if(str[i]==',' || i==len-1){
                if(isS) number = -number;
                Each[allcnt].f[Each[allcnt].fcnt].name = tname;
                Each[allcnt].f[Each[allcnt].fcnt].ope = tope;
                Each[allcnt].f[Each[allcnt].fcnt++].number = number;
                tope="";tname="";number = 0;isS = false;
            }
        }

        //对复合句子本身进行判断,如果本身就是空集,就Pass
        node now = Each[allcnt];
        bool flag = true;
        for(int i=0;i<now.fcnt;i++){
            for(int j=0;j<now.fcnt;j++){
                if(now.f[i].name==now.f[j].name&&now.f[i].number==now.f[j].number&&now.f[i].ope==now.f[j].ope)
                    continue;
                if(!Judge(now.f[i],now.f[j])){
                    Each[allcnt].isRight = false;
                    flag = false;
                    break;
                }

            }
        }
        //对每个式子进行判断
        bool searchflag = false;
        for(int i=0;i<allcnt&&flag;i++)
        {
            node tmp = Each[i];
            if(!tmp.isRight) continue;
            bool ok = true;
            for(int j=0;j<now.fcnt;j++){
                for(int k=0;k<tmp.fcnt;k++){
                    if(!Judge(now.f[j],tmp.f[k])){
                        ok = false;
                        break;
                    }
                }
            }
            if(ok){
                if(searchflag) printf(" ");
                printf("%d",i+1);
                searchflag = true;
            }
        }
        if(!flag||!searchflag){
            printf("unique\n");
        }
        else printf("\n");

        allcnt++;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值