J 螺旋塔
思路:一眼签到题直接写
#include<iostream>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 2e5+10;
string s;
int n;
void solve()
{
cin >> s;
cin >> n;
for(int i=0;i<n;i++)
{
int pos=i;
int num=1;
while(num<=s.size())
{
cout << s[pos%s.size()];
pos++;
num++;
}
cout << endl;
}
return;
}
int main()
{
int t=1;
//cin >> t;
while(t--)
{
solve();
}
return 0;
}
F 借钱难
思路:看题可以知道,只有最亲近的朋友才能借钱,也就是说亲近的朋友可以互相借钱,那么如果当前这个朋友不够钱可以向另一亲近朋友借钱然后再借给另一个朋友,这样子只要最终亲近朋友借钱的总和give等于收到需要借钱的总和need就说明满足条件,然后我们直接并查集记录最亲近的朋友即可
代码实现:
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;
#define int long long
const int N = 2e5+10;
const int mod = 1e9 + 7;
typedef long long LL;
LL a[N], b[N];
LL n,m;
LL f[N];
LL need[N];
LL give[N];
void init()
{
for (int i = 1; i <= n; i++)
{
f[i] = i;
need[i] = 0;
give[i] = 0;
}
}
int find(int x)
{
if (f[x] != x) f[x] = find(f[x]);
return f[x];
}
bool solve()
{
cin >> n >> m;
init();
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
for (int i = 1; i <= n; i++)
{
if (a[i] > b[i]) give[i] = a[i] - b[i];
else need[i] = b[i] - a[i];
}
for (int i = 1; i <= m; i++)
{
LL p1, p2;
cin >> p1 >> p2;
if (find(p1) != find(p2))
{
need[find(p1)] += need[find(p2)];
give[find(p1)] += give[find(p2)];
need[find(p2)] = 0;
give[find(p2)] = 0;
f[find(p2)] = find(p1);
}
}
for (int i = 1; i <= n; i++)
{
if (need[i] != give[i]) return false;
}
return true;
}
signed main() {
int T = 1;
cin >> T;
while (T--)
{
if (solve()) cout << "Yes" << endl;
else cout << "No" << endl;
}
}
E 改题难
思路:由a难度的记忆化搜索变成b难度的dp,这里因为记忆化搜索的难度只能降不能升和变,dp难度只能升和不变,,所以需要分情况考虑 a和b的大小:
情况一:当a>b时,此时只考虑条件一二,由a->b步数为 2*(a-b-1) + 1 ,因为由难度kdp->(k-1)dp,需要走两步,所以要乘2,然后因为一开始走一步变成 a-1,所以就是2*(a-b-1) + 1,同理只考虑条件三,由由a->b步数为 a-b + 1,,因为条件三直接下降,快了条件一二是两部的,所以我们直接枚举x的消费即可,因为起始x必须为一变成dp难度,所以每次下降都是x+2,所以消费就为:x*i + (n-i)/2 * y; i~[1,(a-b-1)*2+1]
情况二:当a<b时,此时因为a需要增大变成b,一开始还是一样需要变成dp难度,不过此时的dp难度没有由 a->(a-1),因为记忆化只能下降不能上升,所以相对于情况一多了一个x,然后直接枚举y的消费算最小值,步数为b-a,,消费为:i*y + x + x*(n-i)*2 ,i~[1,b-a]
代码实现:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 3e3+10;
const int mod = 1e9 + 7;
int n, m, k;
int mp[N];
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
void solve() {
int a,b,x,y;
cin>>a>>b>>x>>y;
int res = 0;
if(a==b){
cout<<x<<endl;
return;
}
if(a>b){
int n = 2*(a-b-1)+1;
res = min(x*n,(n/2)*y+x);
for(int i=1;i<=n;i+=2){
//int t = i/2;
int num = x*i + (n-i)/2 * y;
res = min(res,num);
}
}else{
int n = (b-a);
res = min(x*2*n+x,n*y+x);
for(int i=1;i<=n;i++) //y
{
int t = x*(n-i)*2;
int num = i*y + x + t;
res = min(res,num);
}
}
cout<<res<<endl;
}
signed main() {
int T = 1;
//cin >> T;
while (T--) solve();
}
A 人人有份
emm,,一开始看到题目有点懵圈了,然后直接翻到最下面找样例解释发现,只是找3的几次方和5的几次方相加等于n就可以了, 那这不是直接暴力就完事了嘛,没错就是暴力就可以了
思路:首先我们看到数据范围,n在1e18,在long long范围,然后直接预处理出来3最大在1e18的次幂和5最大在1e18次幂,可以很快找到3在28,5在26,然后直接枚举相加就可以了
#include <iostream>
using namespace std;
#define int long long
const int N = 5e6;
int n, x;
int pow3[50];
int pow5[50];
void init() {
pow3[0] = 0;
pow3[1] = 3;
for (int i = 2; i <= 38; i++)
pow3[i] = pow3[i - 1] * 3;
pow5[0] = 0;
pow5[1] = 5;
for (int i = 2; i <= 26; i++)
pow5[i] = pow5[i - 1] * 5;
/*for (int i = 2; i <= 38; i++)
cout << i << " " << pow3[i] << endl;
for (int i = 2; i <= 26; i++)
cout << i << " " << pow5[i] << endl;*/
}
void solve() {
cin >> n;
for (int i = 1; i <= 38; i++)
{
int a = pow3[i];
for (int j = 1; j <= 26; j++)
{
int b = pow5[j];
//cout << a << " " << b << endl;
if (a+b == n)
{
cout << "Yes" << endl;
return;
}
}
}
cout << "No" << endl;
}
signed main() {
init();
int T;
cin >> T;
while (T--) solve();
return 0;
}
I 联合权值
思路:n的范围很明显很大,再看值的范围,在2e3,T的范围在10,很明显直接用 T*(2e3*2e3),然后我们直接枚举数求最大即可,记录每一个数的最后出现位置还有预处理出来每个数的gcd值等于一,然后从2000开始往下判断找到最大的相加位置,定义初始化res=-1,找不到自动就返回-1了
#include <iostream>
using namespace std;
const int N = 5e6;
int n, x;
int mp[N];
int list[N];
int gcd(int a, int b) {
return b == 0 ? a : gcd(b,a % b);
}
void init() {
for (int i = 2001; i >= 1; i--)
for (int j = 2001; j >= i; j--)
if (gcd(i, j) == 1)
list[i * 2000 + j] = 1;
}
void solve() {
scanf("%d", &n);
for (int i = 1; i <= 2001; i++) mp[i] = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
mp[x] = i;
}
int res = -1;
for (int i = 2001; i >= 1; i--)
for (int j = 2001; j >= i; j--)
if (mp[i]&&mp[j]&&list[i * 2000 + j] == 1)
res = max(res, mp[i] + mp[j]);
cout << res << '\n';
}
int main() {
init();
int T;
cin >> T;
while (T--) solve();
return 0;
}
标签:秋季,int,题解,long,2024,--,solve,include,find
From: https://blog.csdn.net/qq_63707333/article/details/143472054