div3补提
https://codeforces.com/contest/1968
A:需要求gcd(x,y)+y的最大值,给的范围只有1-1000,可以直接暴力来做。
求最大公约数的代码gcd,如果x<y,需要叫交换x和y的值,如果y等于0,就返回x,用递归的形式,return gcd(y,x%y);
#include <bits/stdc++.h>
using namespace std;
int gcd(int x, int y)
{ if(x<y){swap(x,y);}if (y == 0){return x;}else{return gcd(y, x % y);}
}
int main()
{int t;cin >> t;while (t--){int x;cin >> x;int res = 0;int result = 0;for (int i = 1; i < x; i++){int sum = gcd(x, i) + i;if (sum >= res){res = sum;result = i;}}cout << result << endl;}
}
B /判断a有多少时在b里面的 a[i]等于b[i] i就++,不然就移动j,这是经典的双指针问题;
#include <bits/stdc++.h>
using namespace std;
void test()
{int n, m;cin >> n >> m;string a, b;cin >> a >> b;int i = 0, j = 0;while (i < a.size() && j < b.size()){if (a[i] == b[j]){i++;}j++;}// 判断a有多少时在b里面的 a[i]等于b[i] i就++,不然就移动j,这是经典的双指针问题;cout << i << endl;
}
int main()
{int t;cin >> t;for (int i = 0; i < t; i++){test();}
}
C 给定一个数组,找到任意一个数组满足xi=ai和ai-1的取模,xi的下标是从2开始的。x的范围并不是很大,只有五百。
只要找到一个很大的数字开始即可,后面的所有数字都累加上x;因为如果找到一个比较小的数字,累加起来可能会取模为0.
如果现在ai-1 等于14,x等于14,那么怎么找到一个数字模上14等于14呢?所以这个数字就必须大于x才能满足。只要ai大于x的最大范围,都能得到ai+x就是下一个数字的。
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
int a[N];
int main()
{int t;cin >> t;while (t--){int n;cin >> n;int x = 10000;cout << x << " ";for (int i = 1; i <= n - 1; i++){int m;cin >> m;x = x + m;cout << x << " ";}cout << endl;}
}
D
#include<bits/stdc++.h>
using namespace std;
#define yes cout<<"Bodya"<<endl
#define no cout<<"Sasha"<<endl
#define eq cout<<"Draw"<<endl
#define int long long
using ll = long long;
using db = double;
using pii = pair<int, int>;
const int N = 314159;
const int INF = 1e9;signed main() {ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);int t; cin >> t;while (t--) {int n, k, pb, ps; cin >> n >> k >> pb >> ps;vector<int> p(n + 5), a(n + 5);for (int i = 1; i <= n; i++)cin >> p[i];for (int i = 1; i <= n; i++)cin >> a[i];// 分开单纯是为了代码好看int maxi = 0;for (int i = 1; i <= n; i++) maxi = max(maxi, a[i]);int turn = 0; // 第几个回合了int cost = 0; // 前若干个回合的得分int ansb = 0;vector<bool> visb(n + 5);for (int pos = pb;;) {int now = cost + (k - turn) * a[pos]; // 策略只有一种,走到该点后扎根ansb = max(ansb, now);turn++;cost += a[pos];if (a[pos] == maxi)break;visb[pos] = 1;pos = p[pos];if (turn == k || visb[pos])break;}turn = 0;cost = 0;int anss = 0;vector<bool> viss(n + 5);for (int pos = ps;;) {int now = cost + (k - turn) * a[pos]; // 策略只有一种,走到该点后扎根anss = max(anss, now);turn++;cost += a[pos];if (a[pos] == maxi)break;viss[pos] = 1;pos = p[pos];if (turn == k || viss[pos])break;}if (ansb > anss)yes;else if (anss > ansb)no;else eq;}// 最优策略是否一定是往前走到一个较大值之后原地待命?// 走到最大格之后一定最优return 0;
}