Educational Codeforces Round 80 (Rated for Div. 2)题解
A题
div2的A题一般都是思维题或者暴力题,显然本题暴力不可解,但是观察式子,可以得出我们需要求的是y=x+d/(x+1)的最小值,可以求导数,也可以直接构造成初中学习过的不等式
得到ymin=2√d -1,即可求出答案。
#include<iostream> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<map> #include<vector> #include<cstdio> #include <unordered_map> using namespace std; const int N=1e5+10; const int inf=0x3f3f3f3f; typedef long long ll; int main(){ int n; int i,j; int t; cin>>t; while(t--){ int d; cin>>n>>d; if(n>=2*sqrt(d)-1) cout<<"YES"<<endl; else cout<<"NO"<<endl; } }
B题
显然本题不可能暴力求解,那么观察所求等式,可以进行化简,原式为 ab+a+b=cons(a,b)
化简后可以得 b+1 =10ƒ(b) (f(b)是上方指数)
因此式子与a无关,a可以取任何值,只需要求b的个数即可,再观察可得,就是b的位数再加上一个限制条件,如果这个数不形如9,99,999,9999那么b可取的个数就是位数-1,否则就是位数。
注意会爆int
#include<iostream> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<map> #include<vector> #include<cstdio> #include <unordered_map> using namespace std; const int N=1e5+10; const int inf=0x3f3f3f3f; typedef long long ll; int main(){ int n; int i,j; int t; cin>>t; while(t--){ int a,b; cin>>a>>b; int sign=0; int cnt=0; while(b){ cnt++; if(b%10==9) sign++; b/=10; } if(sign==cnt) cout<<(ll)a*cnt<<endl; else cout<<(ll)a*(cnt-1)<<endl; } }
C题
本题是思维+计数dp题
题干有多组条件,根据a是不减序列,b是不增序列,长度为m,且ai<=bi,那么可以总结出am<=bm,那么本题实际上就是求取长度为2m的不减子序列
设计状态f[i][j]为长度为i,第一位是j的不减序列
正序枚举i,倒序枚举j,把所有种类都转移到开头位置,转移方程的意义是,因为状态存放在第一位,倒序枚举j那么所有j+1中包含的j一定包含,并且还包括上一位第一位是j的答案,所以f[i][j]=(f[i][j+1]+f[i-1][j])%mod;
#include<iostream> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<map> #include<vector> #include<cstdio> #include <unordered_map> using namespace std; const int N=1e3+10; const int inf=0x3f3f3f3f; const int mod=1e9+7; typedef long long ll; int f[N][N];//长度为i,第一位是j的非递减个数 int main(){ int n,m; cin>>n>>m; m*=2; int i,j; for(i=1;i<=n;i++){ f[1][i]=1; } for(i=2;i<=m;i++){ for(j=n;j>=1;j--){ f[i][j]=(f[i][j+1]+f[i-1][j])%mod; } } ll ans=0; for(i=1;i<=n;i++){ ans=(ans+f[m][i])%mod; } cout<<ans<<endl; }
没有人不辛苦,只有人不喊疼