《经 典 咏 流 传》

又逢校内测,成绩变化大

初见三道题,暗喜AK辣

谁知数据毒,特判不到家

三题两题WA,心态已爆炸

T1(我不想再见到这道题):

附上多年前AC但是随便出(毒瘤)一组数据就可以卡掉的代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a[10001];
int main()
{
    int n,i;
    cin>>n;
    for(i=n;i>=0;i--)
    {
        cin>>a[i];
    }
    for(i=n;i>=0;i--)
    {
        
        if(a[i]!=0)
        {
            if(i==n)
            {
                if(a[i]==1||a[i]==-1)
                {
                    if(a[i]==1)
                        cout<<"x^"<<i;
                    if(a[i]==-1)
                        cout<<"-x^"<<i;
                }
                else
                    cout<<a[i]<<"x^"<<i;
            }
            if(i!=n&&i!=0&&i!=1)
            {
                if(a[i]==1||a[i]==-1)
                {
                    if(a[i]==1)
                        cout<<"+x^"<<i;
                    if(a[i]==-1)
                        cout<<"-x^"<<i;
                }
                else if(a[i]>0)
                    cout<<"+"<<a[i]<<"x^"<<i;
                else if(a[i]<0)
                    cout<<a[i]<<"x^"<<i;
            }
            if(i==1)
            {
                if(a[i]==1||a[i]==-1)
                {
                    if(a[i]==1)
                    {
                        cout<<"+x";
                    }
                    if(a[i]==-1)
                    {
                        cout<<"-x";
                    }
                }
                else if(a[i]>0)
                    cout<<"+"<<a[i]<<"x";
                else if(a[i]<0)
                    cout<<a[i]<<"x";
            }
            if(i==0)
            {
                if(a[i]>0)
                {
                    cout<<"+"<<a[i];
                }
                if(a[i]<0)
                {
                    cout<<a[i];
                }
            }
        }
        
    }
    return 0;
}

这是之前的码风

这里的毒瘤数据指的是首项为零,(然鹅首项为零就不是n次不等式了...多虑导致WA)

越想越觉得得抽自己一巴掌...

T2:

世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,A 市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根 据计划录取人数的150%划定,即如果计划录取m名志愿者,则面试分数线为排名第m*150% (向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。

AC了,且无需多言,上代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
struct peo{
    int id,sc;
}p[5005];
inline bool cmp(const peo &a,const peo &b){
    if(a.sc!=b.sc) return a.sc>b.sc;
    return a.id<b.id;
}
int main(){
    //freopen("score.in","r",stdin);
    //freopen("score.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&p[i].id,&p[i].sc);
    sort(p+1,p+1+n,cmp);
    int name=int(m*1.5);
    int line=p[name].sc;
    while(p[name+1].sc==line)
        name++;
    printf("%d %d\n",line,name);
    for(int i=1;i<=name;i++)
        printf("%d %d\n",p[i].id,p[i].sc);
    return 0;
}

现在码风多好...不接受反驳

T3:

Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家。现在,他正在为一个细胞实 验做准备工作:培养细胞样本。 Hanks 博士手里现在有 N 种细胞,编号从 1~N,一个第 i 种细胞经过 1 秒钟可以分裂为 Si 个同种细胞(Si 为正整数)。现在他需要选取某种细胞的一个放进培养皿,让其自由分裂, 进行培养。一段时间以后,再把培养皿中的所有细胞平均分入 M 个试管,形成 M 份样本, 用于实验。Hanks 博士的试管数 M 很大,普通的计算机的基本数据类型无法存储这样大的 M 值,但万幸的是,M 总可以表示为 m1的 m2 次方,其中 m1,m2 均为基本 数据类型可以存储的正整数。 注意,整个实验过程中不允许分割单个细胞,比如某个时刻若培养皿中有 4 个细胞, Hanks 博士可以把它们分入 2 个试管,每试管内 2 个,然后开始实验。但如果培养皿中有 5 个细胞,博士就无法将它们均分入 2 个试管。此时,博士就只能等待一段时间,让细胞们继 续分裂,使得其个数可以均分,或是干脆改换另一种细胞培养。 为了能让实验尽早开始,Hanks 博士在选定一种细胞开始培养后,总是在得到的细胞“刚 好可以平均分入 M 个试管”时停止细胞培养并开始实验。现在博士希望知道,选择哪种细 胞培养,可以使得实验的开始时间最早。

时间关系...

未AC代码(改天调):

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n;
int m1,m2;
int s[10005];
inline int gcd(const int &a,const int &b){
    if(b==0) return a;
    return gcd(b,a%b);
}
inline int numcnt(int t,int k){
    int tot=0;
    while(t%k==0){
        t/=k;
        tot++;
    }return tot;
}
inline bool p(const int &nn){
    for(int i=2;i<=sqrt(nn);i++){
        if(!(nn%i)) return 0;
    }return 1;
}
int main(){
    //freopen("data.in","r",stdin);
    //freopen("cell.out","w",stdout);
    scanf("%d",&n);
    scanf("%d%d",&m1,&m2);
    if(m1==1){
        cout<<0<<endl;
        return 0;
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&s[i]);
    int tt=0;
    int pri[30005];
    int numm[30005];
    memset(numm,0,sizeof(numm));
    int ti=m1;
    for(int i=2;i<=ti;i++){
        if(p(ti)){
            pri[++tt]=ti;
            break;
        }
        if(ti%i==0)
            pri[++tt]=i;
        while(ti%i==0){
            ti/=i;
            numm[i]++;
        }
    }
    int minn=10005;
    for(int i=1;i<=n;i++){
        if(gcd(s[i],m1)==1)continue;
        int maxn=0;
        bool ok=1;
        int tot=1;
        int sum=0;
        for(int j=1;j<=tt;j++){
            if(numcnt(s[i],pri[j])==0){
                ok=0;
                break;
            }
            int now=0;
            now=numm[pri[j]]*m2/numcnt(s[i],pri[j]);
            if((numm[pri[j]]*m2)%numcnt(s[i],pri[j]))
                now++;
            maxn=max(maxn,now);
        }
        if(ok==0)continue;
        while(tot<maxn){
            tot*=2;
            sum++;
        }
        minn=min(minn,sum+1);
    }
    if(minn==10005)
        printf("-1");
    else
        printf("%d",minn);
    return 0;
}

AC代码(天天%我但就是比我高的ych代码):

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<time.h>
#include<queue>
#include<stack>
using namespace std;
inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
 } 
 
 //首先这道题显然是道数学题(要不然这数据怎么玩)
 //样例1的解释启发我们这道题可以通过分解质因数做
 //这个题其实条件等价于求a^x=k(m1^m2)的最小x值 
 //我们可以对两边进行分解质因数
 //发现如果方程有解,则m1中不能包含a中没有的质因子 
 //但是a1的质因子可以比m1多 
 //那么最小的x就是找到最大的次数差值 
 
 struct prime
{
    int cnt,pn[30001],t[30001];
}p,q;//一个储存题目给的条件,一个储存判断 
int n,m1,m2;
inline void fenjie(int t,prime& p)//质因数分解2 
{
    p.cnt=0;
    for(int i=2;i*i<=t;++i)
    {
        if(!(t%i))
        {
            p.pn[++p.cnt]=i;//记录第cnt个约数 
            p.t[p.cnt]=0;
            do
            {
                t/=i;
                ++p.t[p.cnt];//次数 
            }while(!(t%i));
        }
    }
     
    if(t>1){
        p.pn[++p.cnt]=t;
        p.t[p.cnt]=1;
    }
}
int main(){
    //freopen("cell.in","r",stdin);
     //freopen("cell.out","w",stdout);
    n=read(),m1=read(),m2=read();
    if(m1==1) return cout<<0<<endl,0;//先判断一波特殊情况 
    fenjie(m1,p);//把m1分解,存到p里 
    int ans,x;
    ans=-1;
    for(int i=1;i<=n;i++)
    {
        x=read();
        fenjie(x,q);
        int maxn=0,nxt=1;
        //我们用nxt来存储x的下一个质因子的序号 
        bool flag=false;
        if(q.cnt>=p.cnt)
    //只有要求判断的数的质因子的个数>=题目给的条件的质因子的个数才能继续 
        for(int j=1;j<=p.cnt;j++)//枚举m1的每一个质因子 
        {
            while(q.pn[nxt]<p.pn[j]&&nxt<=q.cnt)++nxt;
            if(nxt>q.cnt||q.pn[nxt]>p.pn[j])break;//如果没有这个质因子就跳出 
            int f=p.t[j]*m2/q.t[nxt];
            if((p.t[j]*m2)%(q.t[nxt])) f++;
    //让这两个次数相等,因为有可能不整除,所以还要判断一下,相当于向上取整 
            if(maxn<f)maxn=f;//求最大值
            if(j==p.cnt) flag=1; //标记答案 
            else flag=0;
        }
        if(flag&&(ans==-1||ans>maxn))ans=maxn;
    }
    printf("%d\n",ans);
    return 0; 
}

考试时候写题解???EXM???

 

次日update

已AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n;
int m1,m2;
int s[10005];
inline int gcd(const int &a,const int &b){
    if(b==0) return a;
    return gcd(b,a%b);
}
inline int numcnt(int t,int k){
    int tot=0;
    while(t%k==0){
        t/=k;
        tot++;
    }return tot;
}
int main(){
    //freopen("cell.in","r",stdin);
    //freopen("cell.out","w",stdout);
    scanf("%d",&n);
    scanf("%d%d",&m1,&m2);
    for(int i=1;i<=n;i++)
        scanf("%d",&s[i]);
    int tt=0;
    int pri[30005];
    int numm[30005];
    memset(numm,0,sizeof(numm));
    int ti=m1;
    for(int i=2;i<=ti;i++){
        if(ti%i==0)
            pri[++tt]=i;
        while(ti%i==0){
            ti/=i;
            numm[i]++;
        }
    }
    int minn=10005;
    for(int i=1;i<=n;i++){
        int gc=gcd(m1,s[i]);   //~~int gc=cxk;~~
        int maxn=0;
        bool ok=1;
        int tot=1;
        int sum=0;
        for(int j=1;j<=tt;j++){
            if(numcnt(s[i],pri[j])==0){
                ok=0;
                break;
            }
            int now;
            now=numm[pri[j]]*m2/numcnt(s[i],pri[j]);
            if(numm[pri[j]]*m2%numcnt(s[i],pri[j]))
                now++;
            maxn=max(maxn,int(now));
        }
        if(ok==0)continue;
        minn=min(minn,maxn);
    }
    if(minn==10005)
        printf("-1");
    else
        printf("%d",minn);
    return 0;
}

思路与上面的那位大佬一致,也是考试时的思路,代码与考试src基本一致,改了两行AC了,主要就是改进了取整运算,改正了关于minn的算法,可以看出许多变量是没有必要设的,甚至很多语句都是多余的,原因在于懒得删了急于AC,反正也A了嘛...

posted @ 2019-06-18 19:54  _Alex_Mercer  阅读(292)  评论(1编辑  收藏  举报