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;
}