D题
简单的dp,我当时没反应过来 这是 dp,好吧,其实是很久没做题了。(脑袋木了)
题意:n m k
n 长的字符 ,m k 可以跳跃的最大距离(每次跳跃的距离1<= <=m) k 在水里游泳的最大值
字符串 包含 L (表示 是原木,可以进行跳跃。可以跳到水中或者原木上)C (鳄鱼,不可以登上鳄鱼在的地方)W(水)
能否 达到,对岸。输出yes no
典型的动规 dp[i] 代表 到达i 所要游的最少的米数,从两个地方转移。一个是跳着过来的,一个是 游过来的。最后比较 终点的dp值和k的大小。
时间复杂度 O(n*m)
#include <bits/stdc++.h>
using namespace std;void solve()
{int n,m,k;cin>>n>>m>>k;string s;cin>>s;s="L"+s+"L"; 这样处理,方便初始化vector<int>dp(n+2,1e9);dp[0]=0;for (int i=1;i<=n+1;i++){if (s[i]=='C')continue;从前一格的水 转移过来if (s[i-1]=='W') dp[i]=min(dp[i],dp[i-1]+1);跳过来,这里要注意 只有L 可以跳for (int j=1;j<=min(m,i);j++)if (s[i-j]=='L')dp[i]=min(dp[i],dp[i-j]);}if (dp[n+1]<=k)cout<<"YES\n";else cout<<"NO\n";
}
int main()
{std::cin.tie(nullptr)->sync_with_stdio(false);int t;cin>>t;while(t--)solve();return 0;
}
E
题意:
其实这道题就是暴力枚举。
我当时为啥没做出来,反思了一下。
我当时看完题 感觉 脑子一片空白,感觉没怎么思考,就放过去了。也是感觉自己做不下来 div3 的E。
以后即使乍一看没啥思路应该自己 看看样例,搓搓数据。想想暴力。希望能够提升的快一点。感觉赶不上大家的进步速度……(sad)
大致的题意:
na-b(字符串版本,-b相当于 移除 后面的b 个字符 )==na-b(数字版本)
输入 n
输出
符合条件的 a b 对的个数
a b 的值。
分析:
左边表达式的最终的结果 是 若干个n字符组成的 字符串,
右边表达式 的最终结果 不会超过六位数(1e6(七位数字,1后面六个0)-b ,肯定小于等于六位数字)
当等式成立的时候,左边字符串的长度必然小于等于6.
现在已知 n,那么我们可以枚举 a 的数值,和最终结果的位数 来确定b的值。判断等式是否成立。如果成立push 进 vector
同时注意到,最终结果 的字符串不能是空字符串,所以还要小小的判断一下。
#include <bits/stdc++.h>
using namespace std;//返回 x 的位数的
int dec(int x)
{int res=0;while(x){res++;x/=10;} return res;
}
void solve()
{int n;cin>>n;int digit=dec(n);//数字n的位数 vector<pair<int,int>>res;for (int a=1;a<=10000;a++)for (int i=1;i<=min(6,a*digit);i++){string s=to_string (n);//这个 s 表示的是 最终的 结果 ,我的意思是 表达式的结果 while(s.size()<i)s=s+s;while(s.size()>i)s.pop_back();int m=stoll(s);if (m==a*n-(digit*a-i)&&i!=digit*a){res.push_back({a,digit*a-i});} } cout<<res.size()<<endl;for (auto v:res){cout<<v.first<<" "<<v.second<<endl;}
}
int main()
{std::cin.tie(nullptr)->sync_with_stdio(false);int t;cin>>t;while(t--){solve();}return 0;
}