今年的csp-j难度对于我这种蒟蒻来讲看到的第一眼就是做不下去,今年的csp没有了水题,但其实认真分析也是能做出来的,话不多说,直接开始第一题《小苹果》
ok直接上代码,(自认为写的简单易懂)
#include<iostream>
using namespace std;
const int N=1e6+5;
int n,a[N],take,pos,ans,t_n;
int main()
{
cin>>n;
while(take<n)//没拿到n个就拿
{
ans++;
for(int i=1;i<=n;i++){//第i个苹果,有:
if(a[i]==0){
take++;
if(i==n) t_n=ans;
a[i]=1;//标记拿过了
pos=i;
break;
}
}
int cnt3=0;
for(int i=pos+1;i<=n;i++){
if(a[i]==0) cnt3++;
if(cnt3==3){//要拿走
take++;
if(i==n) t_n=ans;
a[i]=1;
cnt3=0;
}
}
}
cout<<ans<<" "<<t_n;
return 0;
}
当我满怀信心的在洛谷上提交时:
却发现只有90分.......QAQ
然后马上发现了问题
#include<iostream>
using namespace std;
int n,flag,pick_end;
long long ans;
int main()
{
cin>>n;
while(n)//当还有苹果,就继续拿:
{
//每次拿t个
ans++;
int t=1+(n-1)/3;
if((n-1)%3==0&&pick_end==0){
pick_end=ans;
}
n-=t;
}
//无非是在草稿纸上多画几遍
cout<<ans<<' '<<pick_end;
return 0;
}
AC
第二题难度陡然上升
继续上代码(我知道你们只看这儿)
#include<iostream>
#include<cmath>
using namespace std;
const int N=1e5+5;
int n,d,v[N],a[N];
int main()
{
cin>>n>>d;
for(int i=1;i<=n-1;i++) cin>>v[i];
for(int i=1;i<=n;i++) cin>>a[i];
int min_0=a[1];
long long duo=0,you,ans=0;
for(int i=1;i<=n-1;i++)
{
//遍历v[N],每一段路,都用最便宜的油走完
if(min_0>a[i]) min_0=a[i];
//更新最便宜的油价
you=ceil((v[i]-duo)*1.0/d);
ans+=you*min_0;
duo+=you*d-v[i];//更新多走的路
}
cout<<ans<<endl;
return 0;
}
还有一种写法:
#include<iostream>
#include<cmath>
using namespace std;
const int N=1e5+5;
int n,d,v[N],a[N];
long long sum[N];
int main()
{
cin>>n>>d;
for(int i=1;i<=n-1;i++){
cin>>v[i];
sum[i]=sum[i-1]+v[i];//第i个站点,到起点的距离
}
for(int i=1;i<=n;i++) cin>>a[i];
//从1号出发,去下一个比他油价低的加油站
int now=a[1];
long long pass=0,dis,you,ans=0;//走过的路
for(int i=2;i<=n-1;i++)
{
//判断什么,就到哪里
if(now>a[i])
{//买油,整数升
//计算花费?走多远->买多少油->花多少钱
dis=sum[i-1]-pass;
//sum[i]表示,i距离起点的距离
you=ceil(dis*1.0/d);//向上取整,多买一升
ans+=you*now;
//更新油价
now=a[i];
pass+=you*d;
}
}//还需要最后走到终点
dis=sum[n-1]-pass;
//sum[i]表示i距离起点的距离
you=ceil(dis*1.0/d);//向上取整,多买一升
ans+=you*now;
cout<<ans<<endl;
return 0;
}
AC
第三题(折磨我三个小时我特么直接放弃)
赛后死磕出来了:
先讲讲骗分:
#include<iostream>
#include<cmath>
using namespace std;
const int N=1e5+5;
int t,m,a,b,c;
int main()
{
cin>>t>>m;
while(t--)
{
cin>>a>>b>>c;
int r=b*b-4*a*c;
if(r<0) cout<<"NO"<<endl;
else if(b==0&&c==0) cout<<0<<endl;
else{
int x1=(-b+sqrt(r))/(2*a);
int x2=(-b-sqrt(r))/(2*a);
cout<<max(x1,x2)<<endl;
}
}
return 0;
}
50分~(就是考试时一分都没骗到QAQ)
上面是玄学解法下面是满分解法:
#include<bits/stdc++.h>
using namespace std;
int t,m,a,b,c;
int gcd(int a,int b){
if(a%b==0) return b;
return gcd(b,a%b);
}
int main(){
cin>>t>>m;
while (t--)
{
cin>>a>>b>>c;
int r=b*b-4*a*c;
if(r<0) cout<<"NO";
else{//输出解
//预处理,化简sqrt(r)
int b2=1;
for(int i=2;i*i<=r;i++){
while (r%(i*i)==0)
{
r/=(i*i);
b2*=i;
}
}
int aa=2*a,bb=-b;
//方便变量运算,(bb+b2sqrt(r0))/aa
//保证+ b2sqrt(r0)/aa更大,因为aa一定>0
if(aa<0) aa=-aa,bb=-bb;
//化简后,srqt内为1,直接省略根号
//并将分子合并。(bb+b2)/2a
if(r==1) bb+=b2;
// bb/aa+b2sqrt(r0)/aa;
int gc1=gcd(abs(bb),aa);
int gc2=gcd(b2,aa);
if(r==0||r==1){//不输出sqrt
if(bb%aa==0) cout<<bb/aa;
else cout<<bb/gc1<<'/'<<aa/gc1;
}
else{
if(bb!=0){//输出q1部分
if(bb%aa==0) cout<<bb/aa<<'+';
else cout<<bb/gc1<<'/'<<aa/gc1<<'+';
}
//输出q2部分
if(b2/gc2!=1) cout<<b2/gc2<<'*';
cout<<"sqrt("<<r<<')';
if(aa/gc2!=1) cout<<'/'<< aa/gc2;
}
}
cout<<endl;
}
return 0;
}
第四题关于图论,在结尾给大家放一下题
(不要问为什么没有代码,因为这个啥必不会)
(看我做的这么辛苦,不妨点个赞和关注再走?)