700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > HBCPC-河北省大学生程序设计竞赛-部分题解

HBCPC-河北省大学生程序设计竞赛-部分题解

时间:2021-03-15 07:14:49

相关推荐

HBCPC-河北省大学生程序设计竞赛-部分题解

这里写目录标题

7-1 理财7-2 B-棋盘7-5 E-求导7-8 H-信号传输7-10 罚时算术

7-1 理财

签到题,用scanf和printf进行格式输出更简单

AC代码:

#include<bits/stdc++.h>using namespace std;int main(){double n,x,y;scanf("%lf %lf %lf",&n,&x,&y);double ans=((n/x)*y)-n;printf("%.4f",ans);return 0;}

7-2 B-棋盘

原本以为很难,然后抱着试一试的心态,找了找规律,感觉这个规律是没有问题的,就写代码了,主要是题目中的棋盘格子是没有障碍物的,每个格子都能走,发现能按照S型路线走,就能有路径,不能按照S型走就一定不存在经过每个格子的路径

在草稿纸上列举了几个棋盘样式分析了一下

AC代码:

#include<iostream> #include<stdio.h>using namespace std;int n,m;int main(){cin>>n>>m;if(n%2==0&&m%2==0) //一定不存在路径{printf("NO");return 0;} printf("YES\n");if(n%2) //行为奇数{for(int i=1;i<=n;i++){if(i%2) {for(int j=1;j<=m;j++){if(i==1&&j==1) continue;if(i==n&&j==m) break;printf("%d %d\n",i,j);}} else{for(int j=m;j>=1;j--){printf("%d %d\n",i,j);}}}} else //列为奇数{for(int j=1;j<=m;j++){if(j%2){for(int i=1;i<=n;i++){if(i==1&&j==1) continue;if(i==n&&j==m) break;printf("%d %d\n",i,j);}}else{for(int i=n;i>=1;i--){printf("%d %d\n",i,j);}}}} return 0;}

7-5 E-求导

模拟即可,多项式每一项的形式只会是A、x、Ax、x^i、Ax ^i 五种情况的一个注意系数和次数不是只为个位数,与字符串的一个字符是不对应的,需要进行字符串分割注意数据范围要开long long,本来以为不用,但是后来发现怎么都过不了,开了以后就过了

AC代码;

#include<bits/stdc++.h>using namespace std;typedef long long LL;string in;int main(){getline(cin,in);in+="+";char a;string sa="";string pre=""; //前一个+-号cout<<"f'(x)=";LL len=in.length();LL i=5;if(in[i]=='-') {i=6; pre="-";}for(;i<len;i++){a=in[i];if(a=='+'||a=='-') //对前面一项求导{if(sa.length()==1&&sa=="x") //只有一个x{cout<<pre<<1;}else if(sa.find('x')==-1) //只有一个A{if(sa.length()+6+pre.length()==len) cout<<0; //只有一项 }else if(sa[sa.length()-1]=='x') //Ax的情况{string num=sa.substr(0,sa.length()-1);LL t=atoi(num.c_str());cout<<pre<<t;}else if(sa[0]=='x') //x^i的情况{string num=sa.substr(2,sa.length()-2);LL mi=atoi(num.c_str());if(mi==2) cout<<pre<<"2x";else cout<<pre<<mi<<"x^"<<mi-1;}else//Ax^i的情况{LL index=sa.find('x');string Ai=sa.substr(0,index);LL A=atoi(Ai.c_str());string ii=sa.substr(index+2,sa.length()-index-2);LL mi=atoi(ii.c_str());if(mi==2) cout<<pre<<A*mi<<'x';else cout<<pre<<A*mi<<"x^"<<mi-1;} sa="";pre=a;}else sa+=a;}return 0; }

7-8 H-信号传输

0/1背包的变题,一看就知道大概是dp的问题,看时间复杂度,只能保持在O(nlogn)下,dp只能是一维的,或者有优化手段与0/1背包不同的是,在某个城市判断是否修基站,不修就直接与dp[i-1]的状态一样,要修就需要从前一个基站转移而来,前一个基站距离当前的基站是多少并不知道,0/1背包中,前一个选择的物品距离当前判断的物品的距离是i-v[i],因此需要枚举这个距离如果是普通的暴力枚举,O(n^2)的时间复杂度,会超时,观察发现满意度和任意基站间的最小距离是有线性关系的,最小距离越大,也就是基站修得越多,满意度就会越少,因此可以二分枚举最小距离来进行求解,时间复杂度为O(nlogn)

AC代码:

#include<iostream>using namespace std;const int N=200005;typedef long long LL;LL a[N];LL dp[N];LL n,w;int main(){cin>>n>>w;for(int i=1;i<=n;i++) cin>>a[i];int l=0,r=n+1,x; //二分任意两个基站间的最小距离 while(l<r){x=(l+r+1)/2; //求得任意两个基站间的最小距离 dp[0]=0;for(int i=1;i<=n;i++) //第i个城市判断是否修基站 {dp[i]=dp[i-1]; //第i个城市不修基站,满意度跟前i-1个城市两个基站间最小距离为x的满意度一样 if(i-x>=0&&i+x<=n+1) //想在第i个城市修基站,至少得与两端的基站保持x的距离 {dp[i]=max(dp[i],dp[i-x]+a[i]); //在该地方修基站,得到的满意度为距离第i个城市为x的城市转移而来 }}if(dp[n]>=w) //满意度太多了,基站修太多了,可以适当增大最小距离取值范围 {l=x;}else r=x-1; //满意度太少,基站修得不够,需要减小最小距离的取值范围 }if(l==0) cout<<-1<<endl; else cout<<l<<endl;return 0;}

7-10 罚时算术

对输入输出做一下简单的处理即可

#include<iostream>using namespace std;int n;int a,b;int main(){char t;cin>>n;cin.get(); //吸收掉换行符for(int i=0;i<n;i++){t=cin.get(); //先读一个看看,然后再放回缓冲区内cin.putback(t);if(t=='-'){cin>>a;cout<<0<<endl;}else{cin>>a>>t>>b;cout<<a+b*20<<endl;}cin.get(); //吸收掉换行符}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。