Test 1 for NOIP: Result for Day1

头大

这个暑假完就要去搞NOIP了。。。

暑假55天也就20次测试。。。为防万一我还是每次测试玩都写个总结。。


Day1 (65/300)

T1 切蛋糕 (55/100)

严重不服
(程序名都写对了但是最后评测系统说未找到源程序T_T)

【问题描述】

BG 有一块细长的蛋糕,长度为n。 n一些人要来BG 家里吃蛋糕, BG把蛋糕切成了若干块(整数长度),然后分给这些人。
为了公平,每个人得到的蛋糕长度和必须相等,且必须是连续的一段。
但是,BG并不知道要有多少人来。他只知道,来的人数为n的约数,且小于n。显然把蛋糕平均分成n
块一定能满足要求。但是,BG想要分出的块数尽量少。现在BG想知道,他要把蛋糕分成至少多少块,才能使得不管多少人来都能满足要求。

【输入】
输入文件名为cake.in。
输入共一个整数n,表示蛋糕的长度。
【输出】
输出文件名为cake.out。
输出共一个整数,表示分出的最少块数。

【输入输出样例1】
cake.in cake.out
6

4

【输入输出样例说明】
4 块长度分别为2、1、1、2。

【输入输出样例2】
cake.in cake.out
15

7

【输入输出样例说明】
7 块长度分别为3、2、1、3、1、2、3。

【数据说明】
对于30%的数据,2 ≤ n ≤ 15;
对于50%的数据,2 ≤ n ≤ 1,000;
对于70%的数据,2 ≤ n ≤ 1,000,000;
对于100%的数据,2 ≤ n ≤ 1,000,000,000。

源程序搞掉了。。
为什么会用到了欧拉函数????这还是信息学竞赛吗???

STD.CPP

#include<iostream>
#include<iomanip>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;

long long n;

int euler(int n)  //蜜汁欧拉
{  
    int res=n;  
    for(int i=2;i*i<=n;i++){  
        if(n%i==0){  
           res=res/i*(i-1);  
           while(n%i==0) n/=i;  
        }  
    }  
    if(n>1) res-=res/n;  
    return res;  
}

int main()
{
    //freopen("cake.in","r",stdin);
    //freopen("cake.out","w",stdout);
    cin >> n;
    cout << n-euler(n) << endl;
}

T2 随机图 (0/100)

【问题描述】

BG 为了造数据,随机生成了一张n个点的无向图。他把定点标号为1~n。根据BG的随机算法,对于一个点对i,j(1<=i<j<=n),他有p‰的概率成为这张图中的一条边i-j。不同的边出现的概率是相互独立的。
为了保证数据的强度,BG要求生成的图中至少要有一个大于等于 4的连通块。于是他
想知道,在不做任何改进的情况下,根据他的算法造出强数据的概率是多少。

【输入】
输入文件名为random.in。
共一行两个整数n,p,中间用一个空格隔开,表示图的点数和边在图上的概率。

【输出】
输出文件名为random.out。
输出共一行一个实数,表示所求的概率。结果保留4 位小数。

【输入输出样例1】
random.in random.out
3 123

0.0000

【输入输出样例2】
random.in random.out
4 500

0.5938

【数据说明】
对于10%的数据,2 ≤ n ≤ 5;
对于30%的数据,2 ≤ n ≤ 7;
对于60%的数据,2 ≤ n ≤ 30;
对于100%的数据,2 ≤ n ≤ 100,0 ≤ p ≤ 1,000。
对于概率还没怎么学的我来说。。呵呵。。
就直接上题解了吧orz

STD.CPP

#include<bits/stdc++.h>
using namespace std;
typedef double db;

db C[150][150];
db f[150][150][150];
int n;
db p,powP[150];

inline int res(int i,int j,int k)
{
    return i-j*2-k*3;
}
inline void pre()
{
    for(int i=1;i<=100;i++)C[i][1]=i;
    for(int i=2;i<=100;i++)
        for(int j=2;j<=i;j++)
        {
            C[i][j]=C[i-1][j-1]+C[i-1][j];
        }
    return;
}

inline void getpow()
{
    powP[0]=1;
    powP[1]=((db)1-p);
    for(int i=2;i<=100;i++)
    {
        powP[i]=powP[i-1]*powP[1];
    }   
}

int main()
{
    pre();
    scanf("%d %lf",&n,&p);
    p/=1000;
    getpow();
    f[1][0][0]=1;
    for(int i=1;i<n;i++)
        for(int j=0;j<=i/2;j++)
            for(int k=0;k<=i/3;k++)
            {
                int R=res(i,j,k);
                f[i+1][j][k]+=f[i][j][k]*powP[i];
                f[i+1][j+1][k]+=R*f[i][j][k]*powP[i-1]*p;
                f[i+1][j-1][k+1]+=2*j*f[i][j][k]*powP[i-1]*p;
                f[i+1][j][k+1]+=C[R][2]*f[i][j][k]*powP[i-2]*p*p;
                f[i+1][j-1][k+1]+=j*f[i][j][k]*powP[i-2]*p*p;
            }
    db ans=0;
    for(int j=0;j<=n/2;j++)
        for(int k=0;k<=n/3;k++)
        {
            ans+=f[n][j][k];
        }
    printf("%.4f",1-ans);
}

又是dp。。。orz

T3 多项式 (10/100)

用一个大神的高精度都不行。。。要超时。。。
gg
题解玄学

【问题描述】

hihi
hihihi

(才发现可以发图片。。。)

MY.CPP(前面一大段都不是我打的)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<cctype>
#include<iomanip>
#include<map>
#include<set>
#include<conio.h>
#include<vector>
#include<queue>
using namespace std;

struct Wint:vector<int>//用标准库vector做基类,完美解决位数问题,同时更易于实现
{
    //将低精度转高精度的初始化,可以自动被编译器调用
    //因此无需单独写高精度数和低精度数的运算函数,十分方便
    Wint(int n=0)//默认初始化为0,但0的保存形式为空
    {
        push_back(n);
        check();
    }
    Wint& check()//在各类运算中经常用到的进位小函数,不妨内置
    {
        while(!empty()&&!back())pop_back();//去除最高位可能存在的0
        if(empty())return *this;
        for(int i=1; i<size(); ++i)
        {
            (*this)[i]+=(*this)[i-1]/10;
            (*this)[i-1]%=10;
        }
        while(back()>=10)
        {
            push_back(back()/10);
            (*this)[size()-2]%=10;
        }
        return *this;//为使用方便,将进位后的自身返回引用
    }
};
//输入输出
istream& operator>>(istream &is,Wint &n)
{
    string s;
    is>>s;
    n.clear();
    for(int i=s.size()-1; i>=0; --i)n.push_back(s[i]-'0');
    return is;
}
ostream& operator<<(ostream &os,const Wint &n)
{
    if(n.empty())os<<0;
    for(int i=n.size()-1; i>=0; --i)os<<n[i];
    return os;
}
//比较,只需要写两个,其他的直接代入即可
//常量引用当参数,避免拷贝更高效

bool operator!=(const Wint &a,const Wint &b)
{
    if(a.size()!=b.size())return 1;
    for(int i=a.size()-1; i>=0; --i)
        if(a[i]!=b[i])return 1;
    return 0;
}

bool operator==(const Wint &a,const Wint &b)
{
    return !(a!=b);
}

bool operator<(const Wint &a,const Wint &b)
{
    if(a.size()!=b.size())return a.size()<b.size();
    for(int i=a.size()-1; i>=0; --i)
        if(a[i]!=b[i])return a[i]<b[i];
    return 0;
}

bool operator>(const Wint &a,const Wint &b)
{
    return b<a;
}

bool operator<=(const Wint &a,const Wint &b)
{
    return !(a>b);
}

bool operator>=(const Wint &a,const Wint &b)
{
    return !(a<b);
}

//加法,先实现+=,这样更简洁高效
Wint& operator+=(Wint &a,const Wint &b)
{
    if(a.size()<b.size())a.resize(b.size());
    for(int i=0; i!=b.size(); ++i)a[i]+=b[i];
    return a.check();
}
Wint operator+(Wint a,const Wint &b)
{
    return a+=b;
}

//减法,返回差的绝对值,由于后面有交换,故参数不用引用
Wint& operator-=(Wint &a,Wint b)
{
    if(a<b)swap(a,b);
    for(int i=0; i!=b.size(); a[i]-=b[i],++i)
        if(a[i]<b[i])//需要借位
        {
            int j=i+1;
            while(!a[j])++j;
            while(j>i)
            {
                --a[j];
                a[--j]+=10;
            }
        }
    return a.check();
}
Wint operator-(Wint a,const Wint &b)
{
    return a-=b;
}

//乘法不能先实现*=,原因自己想
Wint operator*(const Wint &a,const Wint &b)
{
    Wint n;
    n.assign(a.size()+b.size()-1,0);
    for(int i=0; i!=a.size(); ++i)
        for(int j=0; j!=b.size(); ++j)
            n[i+j]+=a[i]*b[j];
    return n.check();
}
Wint& operator*=(Wint &a,const Wint &b)
{
    return a=a*b;
}

//除法和取模先实现一个带余除法函数
Wint divmod(Wint &a,const Wint &b)
{
    Wint ans;
    for(int t=a.size()-b.size(); a>=b; --t)
    {
        Wint d;
        d.assign(t+1,0);
        d.back()=1;
        Wint c=b*d;
        while(a>=c)
        {
            a-=c;
            ans+=d;
        }
    }
    return ans;
}
Wint operator/(Wint a,const Wint &b)
{
    return divmod(a,b);
}
Wint& operator/=(Wint &a,const Wint &b)
{
    return a=a/b;
}
Wint& operator%=(Wint &a,const Wint &b)
{
    divmod(a,b);
    return a;
}
Wint operator%(Wint a,const Wint &b)
{
    return a%=b;
}

Wint pow(const Wint &n,const Wint &k)
{
    if(k.empty())return 1;
    if(k==2)return n*n;
    if(k.back()%2)return n*pow(n,k-1);
    return pow(pow(n,k/2),2);
}
//顺手实现一个快速幂,可以看到和普通快速幂几乎无异
Wint powx(const Wint &n,const Wint &k,const Wint &d)
{
    if(k.empty())return 1;
    if(k==2)return n*n%d;
    if(k.back()%2)return n*pow(n,k-1)%d;
    return pow(pow(n,k/2),2)%d;
}



分割线//
/*
//通过重载运算符,还可以实现++、--、^、!、逻辑运算符等很多运算,十分简单,此处都不写了
int main()//现在你完全可以像int一般便捷地使用Wint,如下
{
    Wint a,b;
    //可以把b改成int型,仍能正常使用
    cin>>a>>b;//其他运算可以直接调用了
    cout<<(a<b)<<endl
        <<(a==b)<<endl
        <<a+b<<endl
        <<a-b<<endl
        <<a*b<<endl
        <<a/b<<endl
        <<a%b<<endl
        <<pow(a,b);
    return 0;
}*/


int main()
{
    //freopen("polynomial.in","r",stdin);
    //freopen("polynomial.out","w",stdout);
    int n;
    Wint k,l,m,t,ans,jud=0;
    Wint a0=0,a1=0,a2=0,a3=0,a4=0,a5=0,a6=0,a7=0,a8=0,a9=0,a10=0;

    cin >> n >> k >> l >> m;
    //cout << n << " " << k << " " << l << " " << m << endl;

    if(n==0)    cin >> a0 ;
    if(n==1)    cin >> a1 >> a0 ;
    if(n==2)    cin >> a2 >> a1 >> a0 ;
    if(n==3)    cin >> a3 >> a2 >> a1 >> a0 ;
    if(n==4)    cin >> a4 >> a3 >> a2 >> a1 >> a0 ;
    if(n==5)    cin >> a5 >> a4 >> a3 >> a2 >> a1 >> a0 ;
    if(n==6)    cin >> a6 >> a5 >> a4 >> a3 >> a2 >> a1 >> a0 ;
    if(n==7)    cin >> a7 >> a6 >> a5 >> a4 >> a3 >> a2 >> a1 >> a0 ;
    if(n==8)    cin >> a8 >> a7 >> a6 >> a5 >> a4 >> a3 >> a2 >> a1 >> a0 ;
    if(n==9)    cin >> a9 >> a8 >> a7 >> a6 >> a5 >> a4 >> a3 >> a2 >> a1 >> a0 ;
    if(n==10)   cin >> a10 >> a9 >> a8 >> a7 >> a6 >> a5 >> a4 >> a3 >> a2 >> a1 >> a0 ;
    //cout << a0 << " " << a1 << " " << a2 << " " << a3 << " " << a4 << " " << a5 << " " << a6 << " " << a7 << " " << a8 << " " << a9 << " " << a10 << " " << endl;

    Wint hi = pow(10,m);

    for(t=k;t<=k+l-1;)
    {
        //cout << "Case " << t-k+1 << ": " << endl;
        if(a0>jud)
        {
            ans += (a0)*(powx(t,0,hi));
            ans %= pow(10,m);   //cout << "Σa0 = " << ans << endl;
        }
        if(a1>jud)
        {
            ans += (a1)*(powx(t,1,hi));
            ans %= pow(10,m);   //cout << "Σa1 = " << ans << endl;
        }
        if(a2>jud)
        {
            ans += (a2)*(powx(t,2,hi));
            ans %= pow(10,m);   //cout << "Σa2 = " << ans << endl;
        }
        if(a3>jud)
        {
            ans += (a3)*(powx(t,3,hi));
            ans %= pow(10,m);   //cout << "Σa3 = " << ans << endl;
        }
        if(a4>jud)
        {
            ans += (a4)*(powx(t,4,hi));
            ans %= pow(10,m);   //cout << "Σa4 = " << ans << endl;
        }
        if(a5>jud)
        {
            ans += (a5)*(powx(t,5,hi));
            ans %= pow(10,m);   //cout << "Σa5 = " << ans << endl;
        }
        if(a6>jud)
        {
            ans += (a6)*(powx(t,6,hi));
            ans %= pow(10,m);   //cout << "Σa5 = " << ans << endl;
        }
        if(a6>jud)
        {
            ans += (a6)*(powx(t,6,hi));
            ans %= pow(10,m);   //cout << "Σa5 = " << ans << endl;
        }
        if(a7>jud)
        {
            ans += (a7)*(powx(t,7,hi));
            ans %= pow(10,m);   //cout << "Σa5 = " << ans << endl;
        }
        if(a8>jud)
        {
            ans += (a8)*(powx(t,8,hi));
            ans %= pow(10,m);   //cout << "Σa5 = " << ans << endl;
        }
        if(a9>jud)
        {
            ans += (a9)*(powx(t,9,hi));
            ans %= pow(10,m);   //cout << "Σa5 = " << ans << endl;
        }if(a10>jud)
        {
            ans += (a10)*(powx(t,10,hi));
            ans %= pow(10,m);   //cout << "Σa5 = " << ans << endl;
        }
        cout << ans << endl;
        ans = 0;
        t = t+1;
    }
    return 0;
}

卵用,只能过一个点

STD.CPP(玄学)

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define K 100000000
#define LEN 8
#define ll long long
using namespace std;

int N,L,M;
struct num
{
    int a[605];
    num() {memset(a,0,sizeof(a)),a[0]=1;}
    num(const char*s)
    {
        memset(a,0,sizeof(a));
        int l=strlen(s);
        a[0]=min(M/LEN+10,(l-1)/LEN+1);
        for (int p=1; l>0; p++)
        {
            int x=0;
            for (int i=max(0,l-LEN); i<l; i++) (x*=10)+=s[i]-48;
            l-=LEN,a[p]=x;
        }
    }
    void operator ++(int)
    {
        a[1]++;
        for (int i=1; a[i]>=K; i++) a[i]-=K,a[i+1]++;
        if (a[a[0]+1]) a[0]++;
        a[0]=min(a[0],M/LEN+10);
    }
    friend num operator +(const num&A,const num&B)
    {
        num C;
        C[0]=max(A[0],B[0]);
        for (int i=1; i<=C[0]; i++)
        {
            C[i]+=A[i]+B[i];
            if (C[i]>=K) C[i]-=K,C[i+1]++;
        }
        if (C[C[0]+1]) C[0]++;
        C[0]=min(C[0],M/LEN+10);
        return C;
    }
    friend num operator -(const num&A,const num&B)
    {
        num C;
        C[0]=A[0];
        for (int i=1; i<=C[0]; i++)
        {
            C[i]+=A[i]-B[i];
            if (C[i]<0) C[i]+=K,C[i+1]--;
        }
        for (;C[0]>1&&!C[C[0]]; C[0]--);
        return C;
    }
    friend num operator *(const num&A,const num&B)
    {
        num C;
        C[0]=min(M/LEN+10,A[0]+B[0]);
        for (int i=1; i<=A[0]; i++)
            for (int j=1; j<=B[0]; j++)
            {
                ll x=1ll*A[i]*B[j]+C[i+j-1];
                C[i+j]+=x/K,C[i+j-1]=x%K;
            }
        for (;C[0]>1&&!C[C[0]]; C[0]--);
        return C;
    }
    int&operator [](int x) {return a[x];}
    const int&operator [](int x) const {return a[x];}
    void print() const
    {
        if (a[0]<=M/LEN)
        {
            printf("%d",a[a[0]]);
            for (int i=a[0]-1; i; i--) printf("%0*d",LEN,a[i]);
            puts("");
        }
        else
        {
            int l=M%LEN,r=M/LEN,b[15],t=0;
            for (int i=1,j=a[r+1]; j&&i<=l; i++,j/=10) b[++t]=j%10;
            for (;t&&!b[t]; t--);
            for (int i=t; i; i--) printf("%d",b[i]);    
            if (!t)
            {
                for (;r>1&&!a[r]; r--);
                printf("%d",a[r]),r--;
            }
            for (int i=r; i; i--) printf("%0*d",LEN,a[i]);
            puts("");
        }
    }
} a[12],f[12][1002],S;

void init()
{
    char s[2005];
    scanf("%d%s%d%d",&N,s,&L,&M),S=s;
    for (int i=N; i>=0; i--) scanf("%s",s),a[i]=s;
}

void doit()
{
    for (int i=1; i<=N+1; i++,S++)
        for (int j=N; j>=0; j--) f[N][i]=f[N][i]*S+a[j];
    for (int i=N-1; i>=0; i--)
        for (int j=1; j<=i+1; j++) f[i][j]=f[i+1][j+1]-f[i+1][j];
    for (int i=2; i<=L; i++) f[0][i]=f[0][1];
    for (int k=N+2; k<=L; k++)
        for (int i=1; i<=N; i++) f[i][k-N+i]=f[i][k-N+i-1]+f[i-1][k-N+i-1];
    for (int i=1; i<=L; i++) f[N][i].print();
}

int main()
{
    //freopen("polynomial.in","r",stdin);
    //freopen("polynomial.out","w",stdout);
    init();
    doit();
    return 0;
}

话说题解都有两个点超时

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值