noip2009 普及组

T1 多项式输出 题目传送门

就是道模拟题咯

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,k;
int main()
{
    n=read(); k=read();
    if(k!=1&&k!=-1) printf("%dx^%d",k,n);
    else{
        if(k==1) printf("x^%d",n);
        else printf("-x^%d",n);
    }
    for(int i=n-1;i;i--){
        k=read(); if(!k) continue;
        if(k>0) printf("+");
        if(k==-1) printf("-");
        if(k!=1&&k!=-1) printf("%d",k);
        if(i!=1) printf("x^%d",i);
        else printf("x");
    }
    k=read(); 
    if(k){
        if(k>0) printf("+");
        printf("%d\n",k);
    }
    return 0;
}
View Code

T2 分数线划定 题目传送门

也算是道水题 sort一波就好了

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=5007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,cnt,mn;
struct node{int w,pos;}e[M];
bool cmp(node a,node b){return a.w!=b.w?a.w>b.w:a.pos<b.pos;}
int main()
{
    n=read(); m=read()*3/2; //printf("[%d]\n",m);
    for(int i=1;i<=n;i++) e[i].pos=read(),e[i].w=read();
    sort(e+1,e+1+n,cmp);
    mn=e[m].w; cnt=m;
    while(e[cnt+1].w==mn&&cnt<n) cnt++;
    printf("%d %d\n",mn,cnt);
    for(int i=1;i<=cnt;i++) printf("%d %d\n",e[i].pos,e[i].w);
    return 0;
}
View Code

T3 细胞分裂 题目传送门

 这个要用到一个结论 

我们将m1分解为一波质数之后可以求出m1由各个质数的几次方(设为h【i】)相乘得到

然后再把h【i】乘上m2

题目就转换成了 吧每个数拆成质数乘积 必须保证组成的质数与m1相同 而每个h【i】的倍数差最大就是这个数的k次方回事m1的m2次方的倍数

再求出所有k取最小值就是答案了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
const int M=15007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int m1,m2,cnt,s[M],h[M];
int n,p,sum,v[M],ans=-1;
bool f;
void prepare(){
    int k=1;
    while(m1!=1){
        k++;
        if(m1%k==0){
            cnt++; s[cnt]=k;
            while(m1%k==0) h[cnt]++,m1=m1/k;
            h[cnt]=h[cnt]*m2;
        }
    }
}
int main()
{
    n=read();
    m1=read(); m2=read(); prepare();
    //for(int i=1;i<=cnt;i++) printf("[%d %d %d]\n",s[i],h[i]/m2,m2);
    for(int i=1;i<=n;i++) v[i]=read();
    for(int i=1;i<=n;i++){
        f=1; p=0;
        for(int j=1;j<=cnt;j++){
            if(v[i]%s[j]==0){
                sum=0;
                while(v[i]%s[j]==0) sum++,v[i]=v[i]/s[j];
                if(h[j]%sum==0) sum=h[j]/sum;
                else sum=h[j]/sum+1;
                if(sum>p) p=sum;
            }
            else{
                f=0;
                break;
            }
        }
        if(f&&(ans==-1||p<ans)) ans=p;
    }
    printf("%d\n",ans);
    return 0;
}
View Code

T4 道路游戏 题目传送门

这道题正解是dp 我们很容易想到枚举起点和步数 但是会很容易超时

这时我们发现有一些信息可以累加而不需要多次计算 这样就可以降低复杂度了 233

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1507;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,p;
int f[M],s[M][M],w[M],sum;
int main()
{
    n=read(); m=read(); p=read();
    for(int i=1;i<=n;i++) 
     for(int j=1;j<=m;j++)
      s[i][j]=read();
    for(int i=1;i<=n;i++) w[i]=read();
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            int last=j-1>0?j-1:n;
            sum=s[last][i];
            for(int k=1;k<=p;k++){
                if(i-k<0) break;
                f[i]=max(f[i],f[i-k]-w[last]+sum);
                last=last-1>0?last-1:n;
                sum+=s[last][i-k];
            }
        }
    }
    printf("%d\n",f[m]);
    return 0;
}
View Code

 

posted @ 2017-07-19 22:17  友人Aqwq  阅读(224)  评论(0编辑  收藏  举报