NOIP2009年普及组题解

这是第一题:https://www.luogu.org/problemnew/show/P1067
这道题嘛,真的是一道模拟题啊,只要细心一点,把题目中要考虑的情况全都囊括进去,然后再注意一下符号问题就好了。
直接上代码~~~

#include
#include
using namespace std;
int n,a[110];

int main()
{
    //freopen("poly.in","w",stdin);
    //freopen("poly.out","r",stdout);
    int n;
    cin>>n;
    for(int i=n;i>=0;i--)
       cin>>a[i];
    for(int i=n;i>=0;i--){
        if(a[i]>0&&i!=n)
            cout<<'+';
        if(a[i]!=0){
            if((a[i]!=1||i==0)&&a[i]!=-1)
                cout<if(a[i]==-1){
                cout<<'-';
                if(i==0)
                    cout<<1;
            }
            if(i>0)
                cout<<'x';
            if(i>1)
                cout<<'^'<return 0;
}

第二题的题干https://www.luogu.org/problemnew/show/P1068
这道题,是一道简单的排序问题,具体实现就直接看代码吧~~~

#include
#include
#include
#include
using namespace std;
int lastnum;

struct paiming
{
    int hao,fen;
}a[5100],b[5100];

void merge(int l,int m,int r)
{
    int k=l,i=l,j=m+1;
    while(i<=m&&j<=r){
        if(a[i].fen>a[j].fen||(a[i].fen==a[j].fen&&a[i].hao//正如题目描述的那样: 排一下序,先不做什么其他的操作 
            b[k++]=a[i++];
        }
        else{
            b[k++]=a[j++];
        }
    }
    while(i<=m)b[k++]=a[i++];
    while(j<=r)b[k++]=a[j++];
    for(int i=l;i<=r;i++)a[i]=b[i];
}

void mergesort(int l,int r)
{
    if(l>=r)
        return;
    int m=(l+r)/2;
    mergesort(l,m);
    mergesort(m+1,r);
    merge(l,m,r);
}

int main()
{
    freopen("score.in","w",stdin);
    freopen("score.out","r",stdout);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;++i){
        cin>>a[i].hao>>a[i].fen;
    }
    srand(100000);
    mergesort(1,n);//对a[1]到a[n]进行排序 
    int xian=floor(m*1.5);//在这里floor函数是往下取整 
    for(int i=1;i<=n;++i){
        if(a[i].fen1;
            break;
        }//确定出人数来 
    }
    cout<" "<for(int i=1;i<=lastnum;++i)
        cout<" "<return 0;
}

这是第三题:
https://www.luogu.org/problemnew/show/P1069
这道题运用了一些数学的小知识
NOIP2009年普及组题解_第1张图片
之后,当然就是附上代码了~~~

#include
#include
#include
#include
using namespace std;
const int maxN=3001000;
int num2,p[30][2],t[30][2],num1;
int a[maxN],n,m1,m2,s,ans=-1;

void fenjie(int x)
{
    num1=0;
    int i=2;
    memset(a,0,sizeof(a));
    while(i*i<=x){
        if(x%i==0){
            num1++;
            t[num1][0]=i;
            t[num1][1]=0;
            while(x%i==0){
                t[num1][1]++;
                x/=i;
            }
            t[num1][1]*=m2;
        }
        i++;
    }
    //先将m1分解成为质数相乘的形式,然后再在每一个指数上乘上一个m2
    //如果直接算出m1^m2的话,按照题目给的数据范围,是根本行不通的 
    if(x>1){
        num1++;
        t[num1][0]=x;
        t[num1][1]=m2;
    }
}


int main()
{
    cin>>n>>m1>>m2;
    fenjie(m1);
    for(int i=1;i<=n;i++){
        cin>>s;
        bool ok=true;
        int temp=0;
        for(int j=1;j<=num1;j++){
            if(s%t[j][0]!=0){
                ok=false;
                break;
            }
            int x=0;
            while(s%t[j][0]==0){
                x++;
                s/=t[j][0];
            }
            temp=max(temp,(t[j][1]-1)/x+1);
        }
        //每加入一种新的细胞考虑的时候,先将其分解成为质数相乘的形式
        //然后比较每一个质因数,如果m1所拥有的质因数s[i]里面没有,那么无论怎么样,都不可能实现,这个时候就直接退出 
        //如果说判定在有限的次数内可以完成目标,那么考虑每一项质因数的指数
        //当且仅当所有质因数的指数都比m1^m2的大的时候,才能分解 
        if(ok){
            if(ans==-1||ans>temp)
                ans=temp;
        }
    }
    cout<return 0;
}

这道是第四题(好吧,本来难度是很大的,但是我做过~~~)https://www.luogu.org/problemnew/show/P1070
(怎么办,我想把原来的题解搬上来,逃~(≧▽≦)/)

先说状态转移方程:f[i][j]表示在i时刻在j工厂买了一个机器人
f[i][j]=max{f[i+k][y]+sum-need[j]}(其中sum表示从第i时刻开始,机器人从第j个工厂开始收集金币,经过k步所能收集的金币数,money表示从j工厂买机器人需要的金币数,0<=y<=n-1)
如果不采用任何优化的话,只能得40%的分,我们先采取第一步优化:在状态转移的过程中,我们枚举了i,j,k,y。数据范围是200的时候就爆了。其实我们完全可以不需要枚举y。我们可以用opt数组来存储第i行f[i][j]的最大值,要用的时候直接调用就行了(不需要再枚举一遍j)

如果还是有什么不能理解的地方,就直接看程序吧:

#include
#include
using namespace std;
const int maxans=100100;
const int maxN=1100; 
int n,m,p,a[maxN][maxN],f[maxN][maxN],need[maxN],opt[maxN];
int s[maxN][maxN],queue[maxN][maxN][2],head[maxN],tail[maxN];

void readin()
{
    cin>>n>>m>>p;
    for(int i=0;ifor(int j=0;jcin>>a[j][i];
        }
    }
    for(int i=0;icin>>need[i];
    for(int i=0;i0][i]=a[0][i];
    for(int i=0;i<=m-1;i++){
        for(int j=0;j1][(j+1)%n]=s[i][j]+a[i+1][(j+1)%n];//这就是上面说的状态转移方程 
        }
    }
}

void work()
{
    for(int i=0;i1;
    for(int i=m-1;i>=0;--i)
        opt[i]=-maxans;
    for(int i=m-1;i>=0;--i){
        for(int j=0;jint k=(j-i+n)%n;
            int x=opt[i+1]+s[i][j];
            int maxstep=min(m-i,p);
            while(tail[k]>=head[k]&&x>=queue[k][tail[k]][1])
                tail[k]--;
            queue[k][++tail[k]][0]=i+1;
            queue[k][tail[k]][1]=x;
            if(queue[k][head[k]][0]>i+maxstep)
                head[k]++;
            f[i][j]=queue[k][head[k]][1]-need[j];
            if(i>0)
                f[i][j]-=s[i-1][(j+n-1)%n];
            opt[i]=max(opt[i],f[i][j]);
        }
    }
}

int main()
{
    //freopen("game.in","w",stdin);
    //freopen("game.out","r",stdout);
    readin();
    work();
    cout<0]<return 0;
}

你可能感兴趣的:(C++,Junior,NOIP)