Educational Codeforces Round 139 (Rated for Div. 2)

题目链接

1|0A

核心思路:这个其实就是一个简单的dp

  1. 状态定义:dp[i]表示的是1i中的完美数的个数
  2. 状态划分:这个还是比较显然的,我们只需要根据最后一个位置进行状态划分就好了。就分为加了1之后的一个种类变化
  3. 状态转移方程:
  • 如果i是一个完美数,那么dp[i]=dp[i-1]+1;
  • 如果i不是一个完美数,那么dp[i]=dp[i-1];

代码:

#include<bits/stdc++.h> using namespace std; typedef long long LL; #define IOS std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) const int INF = 0x3fff; const int N = 1e7+10, S = 55, M = 10000010; int dp[N]; void Init() { for (int i = 1;i < N;i++) { int y = i; int flag = 0; while (y) { if (y % 10 != 0) flag++; y /= 10; } if (flag == 1) dp[i] = dp[i - 1] + 1; else dp[i] = dp[i - 1]; } } void solve() { int n; cin >> n; cout << dp[n]<<endl; } int main() { Init(); int T; cin >> T; while (T--) { solve(); } }

PS:还有另外一种做法就是找规律,不过有时候找不出就有点坐牢。所以还是推荐第一种做法。


2|0B

核心思路:其实这个很简单我们只需要找出一对字符串是相等的。那么就必然是相等的 ,刚开始粗心读错了题目。实际上那个n我们字符串的长度。所以我们老样子先从一般出发,先考虑三个字符的情况也就是s[i],s[i-1],s[i-2].这里我们可以采用mp来帮助我们存储某些字符是否出现过。代码还是比较简单的.

#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6; int a[N]; int b[N]; bool used[26][26]; void solve() { for (int i = 0;i <= 25;i++) for (int j = 0;j <= 25;j++) used[i][j] = false; int n; string s; cin >> n >> s; for (int i = 1;i <n;i++) { if (used[s[i] - 'a'][s[i - 1] - 'a']) { cout << "YES" << endl; return; } else if (i!=1) used[s[i - 1] - 'a'][s[i - 2] - 'a'] = true; } cout << "NO" << endl; return; } int main() { int T; cin >> T; while (T--) { solve(); } }

3|0C

核心思路:其实这个题目的意思也就是要求我们把地图上面的B全都走完,并且不允许我们回退。所以其实我们的合法路径只有这种形式:

. . . . . . . . . . . . . . .

所以我们先竖着把这些B全都走完,在横向移动。

#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6; int a[N]; int b[N]; bool used[26][26]; void solve() { int n; string s[2]; cin >> n; cin >> s[0] >> s[1]; for (int t = 0;t < 2;t++) { int x = t; int flag = 1; for (int i = 0;i < n;i++) { if (s[x][i] != 'B') flag = 0; if (s[!x][i] == 'B') x ^= 1; } if (flag) { cout << "YES" << endl; return; } } cout << "NO" << endl; } int main() { int T; cin >> T; while (T--) { solve(); } }

4|0D

核心思路:这个题目其实也是不难的,反正数论的 题目我最喜欢做了。但是有一个需要注意的是这里会卡输入和输出如果我们采用的是普通的质数筛,所以需要记得关闭输入和输出流。接下来分析一下。首先我们可以联想一下辗转相除法来对这个题目进行一个化简:gcd(x+k,y+k)=gcd(y+k,yx)=1,然后我们就会发现y-x=d是个常数,而我们的题目是要我们求最小的k使得y+k和d互质,于是我们可以转换为他们的临界条件:也就是他们不互质的时候。换句话说就是y+k可以被d整除。也就是也就是我们对d分解质因数p,然后可以得书出y+k=0(mod),这样搞出来我们会发现这是个负数,也就是k=-y.所以我们需要把他转换一下,也就是k=(p-y%p)%p,这是我们最基本的转为最小正整数的一个方法.

#include <iostream> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef pair<int, int> PII; const int N = 3200, M = 2 * N, INF = 0x3f3f3f3f; int n, m, a[N]; int p[N], pe[N], primes[10000010], cnt; bool st[10000010]; void init() { for (int i = 2; i < N; i++ ) { if(!st[i]) primes[cnt++ ] = i; for (int j = 0; primes[j] * i < N; j++ ) { st[primes[j] * i] = true; if(i % primes[j] == 0) break; } } } void solve() { int a, b; cin >> a >> b; if(a > b) swap(a, b); int t = b - a; int d = __gcd(a, b); if (d > 1) { cout << 0 << '\n'; return ; } int cur = 0, ans = INF; while(primes[cur] <= sqrt(t)) { if(t % primes[cur]) { cur++ ; continue; } while(t % primes[cur] == 0) t /= primes[cur]; ans = min(ans, primes[cur] - a % primes[cur]); cur++ ; } if(t > 1) ans = min(ans, t - a % t); if(ans == INF) ans = -1; cout << ans << '\n'; } signed main() { ios::sync_with_stdio(0),cin.tie(0); // freopen("input.txt", "r", stdin); init(); int T = 1; cin >> T; while(T -- ) solve(); return 0; }

__EOF__

本文作者肖英豪
本文链接https://www.cnblogs.com/xyh-hnust666/p/16980992.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   努力的德华  阅读(74)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示