又逢校内测,成绩变化大
初见三道题,暗喜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了嘛...