2016"百度之星" - 资格赛(Astar Round1) 题解

  • Problem B
  • Problem D

Problem B

度熊面前有一个全是由1构成的字符串,被称为全1序列。你可以合并任意相邻的两个1,从而形成一个新的序列。对于给定的一个全1序列,请计算根据以上方法,可以构成多少种不同的序列。
1≤N≤200

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdio>
#include <string>
#include <algorithm>

using namespace std;

#define LL long long
#define ULL unsigned long long
#define LD long double

#define Rep(x,y,i) for (int i=x;i<y;i++) //[x,y)
#define RepD(x,y,i) for (int i=x;i>y;i--) //(y,x]
#define Mem(X) memset(X,0,sizeof(X));
#define Pr(X) cout<<" "<<#X<<"="<<X<<" ";
#define PrL(X) cout<<#X<<" = "<<X<<endl;
#define PrLL cout<<endl;
using namespace std;
const double EPS = 1e-10;


#define IntMod 10000
struct BigInt
{
private:
    vector<int> A;
    bool Positive;
    int VecNum;

public:
    //Constructors
    inline int GetLength(LL a) {int t=0; while (a>0) {a/=IntMod; t++;} return t;}
    BigInt() { Positive = 1; VecNum = 0; }
    BigInt(const BigInt &a) { A = a.A; VecNum = a.VecNum; Positive = a.Positive; }
    BigInt(string s)
    {
        A.reserve(100);
        if (s == "-0") { A.push_back(0); Positive = 1; VecNum = 1; return; }
        int kk = 3; int kl = 0;
        int l = s.length();
        int j = l - 1;
        if (s[0] == '-') { Positive = 0; kk++; kl++; }
        else Positive = 1;
        while (j>kk)
        {
            int t = 0;
            Rep(0, 4, i) { t *= 10; t += s[j - (3 - i)] - '0'; }
            j -= 4;
            A.push_back(t);
        }
        int t = 0;
        int k = j + 1;
        Rep(kl, k, i) { t *= 10; t += s[i] - '0'; }
        A.push_back(t);
        VecNum = A.size();
    }
    BigInt(const LL &b)
    {
        LL a=b;
        Positive=(a>=0);
        VecNum=GetLength(abs(a));
        A.resize(VecNum);
        Rep(0,VecNum,i)
        {
            A[i]=a%IntMod;
            a/=IntMod;
        }
    }
    //BigInt& operator = (BigInt& a) { VecNum=a.VecNum; Positive=a.Positive; A=a.A; }
    BigInt& operator = (const string s) { BigInt x(s); *this=x; }
    BigInt& operator = (LL s) { BigInt x(s); *this = x; }

    //Basic Math Functions
    friend BigInt abs(BigInt a) { a.Positive=1; return a; }
    friend bool isnegative(BigInt &a) { return a.Positive; }
    BigInt& operator - () { Positive = !(Positive); return *this; }

    // Ostream and Instream
    friend ostream& operator << (ostream &out, BigInt &a)
    {
        if (a.VecNum==0)
        {
            out<<"0";
            return out;
        }   //Bug Fixed if there is a BigInt constructed by the default constructor
        if (!a.Positive) out << "-";
        out << a.A[a.VecNum - 1];
        RepD(a.VecNum - 2, -1, i)
        {
            if (a.A[i] == 0) { out << "0000"; continue; }
            Rep(0, (int)(4 - log(a.A[i]) / log(10) - EPS), j) out << '0';
            out << a.A[i];
        }
        return out;
    }
    friend istream& operator >> (istream &in, BigInt &a)
    {
        string s;
        in >> s;
        int L = s.length() - 1;int i = 0;bool flag = 0;
        if (s[i] == '-') { i++; flag = 1; }
        while (s[i] == '0' && i < L) i++;
        string b(s.begin() + i, s.end());
        if (flag) b.insert(0, "-");
        a = BigInt(b);
        return in;
    }

    //Bool Operators
    bool operator < (const BigInt &b) const
    {
        if (Positive &&  b.Positive)
        {
            if (VecNum != b.VecNum) return (bool)(VecNum<b.VecNum);
            RepD(VecNum-1, -1, i)
                if (A[i] != b.A[i])
                    return (bool)(A[i]<b.A[i]);
            //Bug Fixed that there should be a RepD rather that Rep
            return 0;
        }
        if (!Positive &&  b.Positive) return 1;
        if (Positive && !b.Positive)  return 0;
        BigInt a = b;
        BigInt c = (*this);
        if (!c.Positive && !a.Positive) return !((-c) < (-a));
        return 1;
    }
    bool operator >  (const BigInt &b) const { return !((*this)<b); }
    bool operator == (const BigInt &b) const { return (Positive == b.Positive && A == b.A && VecNum == b.VecNum); }
    bool operator <= (const BigInt &b) const { return (*this == b) || (*this < b); }
    bool operator >= (const BigInt &b) const { return (*this == b) || !(*this < b);}
    bool operator != (const BigInt &b) const { return !(*this == b); }

    bool operator <  (const string b) const { BigInt x(b); return (*this) < x; }
    bool operator == (const string b) const { BigInt x(b); return x==(*this) < x; }

    bool operator <  (const LL& b) const { BigInt x(b); return *this < x; }
    bool operator == (const LL& b) const { BigInt x(b); return *this == x; }

    //Function of Plus and Minus
    BigInt operator - (const BigInt &b) const
    {
        BigInt x=*this;
        BigInt y=b;

        if (!x.Positive &&  y.Positive) return -(-x + y);
        if ( x.Positive && !y.Positive) return x + y;
        if (!x.Positive && !y.Positive) return (-y) - (-x);
        if (x<y) return  -(y - x);

        int L = max(x.VecNum, y.VecNum);
        y.A.resize(L);
        x.A.resize(L);
        Rep(0, L, i)
        {
            x.A[i] -= y.A[i];
            if (x.A[i]<0) { x.A[i] += IntMod; x.A[i + 1]--; }
        }
        while (x.A[L - 1] == 0 && ((L-1)!=0) ) { x.VecNum--; x.A.pop_back(); L--; }
        return x;
    }
    BigInt operator + (const BigInt &b) const
    {
        BigInt x=*this;
        BigInt y=b;

        if (!x.Positive &&  y.Positive) return y - (-x);
        if (!x.Positive && !y.Positive) return -(-x + (-y));
        if ( x.Positive && !y.Positive)  return x - (-y);
        int L = max(x.VecNum, y.VecNum);
        x.A.resize(L + 1);
        y.A.resize(L + 1);
        for (int i = 0; i<L; i++) x.A[i] += y.A[i];
        for (int i = 0; i<L; i++)
        { x.A[i + 1] += x.A[i] / IntMod; x.A[i] %= IntMod; }
        x.VecNum = L;
        if (x.A[L]) x.VecNum++;
        else x.A.erase(x.A.begin() + L);
        return x;
    }
    BigInt operator - (const LL &b) const { BigInt y(b); return *this - y; }
    BigInt operator + (const LL &b) const { BigInt y(b); return *this + y; }
    BigInt operator - (const string b) const { BigInt y(b); return *this - y; }
    BigInt operator + (const string b) const { BigInt y(b); return *this + y; }
    BigInt operator += (const BigInt& b) { *this=*this+b; return *this; }
    BigInt operator += (const LL& b)     { *this=*this+b; return *this; }
    BigInt operator -= (const BigInt& b) { *this=*this-b; return *this; }
    BigInt operator -= (const LL& b)     { *this=*this-b; return *this; }


    //Function of Multiply and Division
    BigInt operator * (const BigInt& b) const
    {
        BigInt x=*this;
        BigInt y=b;
        BigInt ans;
        if ((x.Positive && y.Positive) || (!x.Positive && !y.Positive)) ans.Positive=1;
        else ans.Positive=0;
        int m=x.VecNum,n=y.VecNum;
        int L=m+n+1;
        ans.VecNum=L;
        ans.A.resize(L+3);
        Rep(0,m,i)
            Rep(0,n,j)
            {
                int pos=i+j;
                LL t=x.A[i]*y.A[j];
                int post=0;
                while (t>0)
                {
                    ans.A[pos+post]+=t%IntMod;
                    t/=IntMod;
                    post++;
                }
            }
        Rep(0,L,i) { ans.A[i + 1] += ans.A[i] / IntMod; ans.A[i] %= IntMod; }
        while (ans.A[L - 1] == 0 && ((L-1)!=0) ) { ans.VecNum--; ans.A.pop_back(); L--; }
        return ans;
    }
    BigInt operator * (const LL &b) const    { BigInt x(b); return (*this) * x; }
    BigInt operator * (const string b) const { BigInt x(b); return (*this) * x; }
    BigInt operator *= (const BigInt& b){ *this = *this * b; return *this; }
    BigInt operator *= (const LL &b)    { *this = *this * b; return *this; }
    BigInt operator *= (const string b) { *this = *this * b; return *this; }


    //Function of BITS
}f[201];

int main()
{
    LL a=1;
    f[1]=BigInt(1);
    f[2]=BigInt(2);

    for(int i=3;i<=200;i++) f[i]=f[i-1]+f[i-2];
    int n;
    while(scanf("%d",&n)!=EOF) {
        cout<<f[n]<<endl;
    } 

    return 0;
}

Problem D

度熊所居住的 D 国,是一个完全尊重人权的国度。以至于这个国家的所有人命名自己的名字都非常奇怪。一个人的名字由若干个字符组成,同样的,这些字符的全排列的结果中的每一个字符串,也都是这个人的名字。例如,如果一个人名字是 ACM,那么 AMC, CAM, MAC, MCA, 等也都是这个人的名字。在这个国家中,没有两个名字相同的人。

度熊想统计这个国家的人口数量,请帮助度熊设计一个程序,用来统计每一个人在之前被统计过多少次。

这里包括一组测试数据,第一行包含一个正整数NNN,接下来的NNN 行代表了 NNN 个名字。NNN 不会超过100,000100,000100,000,他们的名字不会超过40位.

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p]) 
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define fi first
#define se second
typedef long long ll;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
map<string,int> h;
map<string,int>::iterator it;

string s;
int main()
{
// freopen("d.in","r",stdin);
// freopen(".out","w",stdout);

    int n;
    scanf("%d",&n);
    For(i,n) {
        cin>>s;
        sort(s.begin(),s.end());
        it=h.find(s);
        if (it==h.end()){
            h[s]=1;
            puts("0");
        }else {
            printf("%d\n",(it->se)++);

        }
    }

    return 0;
}

你可能感兴趣的:(2016"百度之星" - 资格赛(Astar Round1) 题解)