Codeforces Round #702 (Div. 3)个人总结

https://codeforces.com/contest/1490/problem/A
A. Dense Array
题意:
给定一个数组a[],长度为n;
对任意的 1<=i<n-1;要求满足最少插入几个数字
在这里插入图片描述
思路:
贪心的做没必要分a[i]>a[i+1],和a[i+1]>a[i]只有能够连接就行
从前往后扫一遍就行。
参考代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define mp make_pair
#define SZ(a) (int)a.size()
using namespace std;
typedef pair<LL, int> Pll;
const LL INF = 1e13;
#define x first
#define y second
const int N = 100;
LL a[N];
LL f(LL x, LL y)
{
	LL res = 0;
	if (x > y)swap(x, y);
	while (2 * x < y)res++, x = x * 2;
	return res;
}
void solve()
{
	LL sum = 0, n;
	scanf("%lld", &n);
	for (int i = 1; i <= n; i++)scanf("%lld", &a[i]);
	for (int i = 1; i < n; i++)
	{
		sum += f(a[i], a[i + 1]);
	}
	printf("%lld\n", sum);
}
int main()
{
	int T; scanf("%d", &T);
	while (T--)
	{
		solve();
	}
	return 0;
}

https://codeforces.com/contest/1490/problem/B
B. Balanced Remainders
题意:
给你一个序列a[],长度为n;(n=3*k,1<=k<=1e4)
一个操作每次可以使任意的a[i] (1<=i<=n)加一;
现在使每个数模3的余数的为0,1,2;的数的个数都相等;
思路:
扫一遍记录每个余数为0,1,2,的个数;
每次操作只能加一然后暴力去枚举;
参考代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define mp make_pair
#define SZ(a) (int)a.size()
using namespace std;
typedef pair<LL, int> Pll;
const LL INF = 1e13;
#define x first
#define y second
const int N = 100;
void solve()
{
	LL n;
	scanf("%lld", &n);
	LL c[3] = { 0 };
	for (int i = 0; i < n; i++)
	{
		LL x; scanf("%lld", &x);
		c[x % 3]++;
	}
	LL ave = (c[0] + c[1] + c[2]) / 3;
	LL sum = 0;
	while (1)
	{
		bool flag = 1;
		for (int i = 0; i < 3; i++)
		{
			if (c[i]>ave)
			{
				sum += c[i] - ave;
				c[(i + 1) % 3] += c[i] - ave;
				c[i] = ave;
				flag = 0;
			}
		}
		if (flag)break;
	}
	printf("%lld\n", sum);

}
int main()
{
	int T; scanf("%d", &T);
	while (T--)
	{
		solve();
	}
	return 0;
}

https://codeforces.com/contest/1490/problem/C
C. Sum of Cubes
题意:
给你一个x是否满足x=aaa+bbb;(1<=a,b)
数据范围小直接Hash打表
参考代码;

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#include<unordered_map>
#define LL long long
#define mp make_pair
#define SZ(a) (int)a.size()
using namespace std;
typedef pair<LL, int> Pll;
const LL INF = 1e12;
#define x first
#define y second
unordered_map<LL, int> Hash;
void init()
{
	for (LL i = 1; i * i * i <= INF; i++)Hash[i * i * i]++;
}
void solve()
{
	LL x; scanf("%lld", &x);
	bool key = false;
	for (LL i = 1; i * i * i <= INF; i++)
	{
		LL b = x - i * i * i;
		if (b <= 0)break;
		if (Hash[b]) { key = true; break; }
	}
	if (key)puts("YES");
	else puts("NO");
}
int main()
{
	init();
	int T; scanf("%d", &T);
	while (T--)
	{
		solve();
	}
	return 0;
}

https://codeforces.com/contest/1490/problem/D
D. Permutation Transformation
思路:
迪卡尔树
参考代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
using namespace std;
const int N = 109;
struct NODE {
    int pos, val, res;
}a[N];
void merge(int l, int r,int step)
{

    if (l >r)return;
    int mid = l;
    for (int i = l; i <= r; i++)
    {
        if (a[mid].val < a[i].val)mid = i;
    }
    a[mid].res = step;
   // cout << "mid " << mid << " step " << step << endl;
    merge(l, mid-1, step + 1);
    merge(mid + 1, r, step + 1);
}
void solve()
{
    int n; cin >> n;
    for (int i = 1; i <= n; i++) { cin >> a[i].val; a[i].pos = i; }
    merge(1, n, 0);
    for (int i = 1; i <= n; i++)cout << a[i].res << " "; cout << endl;
}
int main()
{
    int t; scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

https://codeforces.com/contest/1490/problem/E
E. Accidental Victory
题意:
给你个序列a[],长度为n;
每次可以选任意大于0的两个数a[i],a[j];
进行合并:1.大的数吞掉小的2.如果a[i]==a[j]随机选择一个数吞掉另一个数。
被吞掉的数变为0,另一个数变为a[i]+a[j];
if(a[i]==a[j])随机
if(a[i]!=a[j])大的吞小的;
参考代码:
思路:
排序加二分

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#include<unordered_map>
#define LL long long
#define mp make_pair
#define SZ(a) (int)a.size()
#define x first
#define y second
using namespace std;
typedef pair<LL, int> Pll;
const LL INF = 1e12;
const int N = 2e5 + 10;
Pll a[N];
void solve()
{
	int n; scanf("%d", &n);
	for (int i = 1; i <= n; i++)scanf("%lld", &a[i].x), a[i].y = i;
	sort(a + 1, a + 1 + n);
	int l = 0, r = n;
	int res = 0;
	while (l <= r)
	{
		int mid = (l + r) >> 1;
		LL sum = 0;
		for (int i = 1; i <= mid; i++)sum += a[i].x;
		bool tag = true;
		for (int i = mid + 1; i <= n; i++)
		{
			if (sum < a[i].x) { tag = false; break; }
			sum += a[i].x;
		}
		if (tag)r = mid - 1, res = mid;
		else l = mid + 1;
	}
	vector<int> ans;
	for (int i = res; i <= n; i++)ans.push_back(a[i].y);
	printf("%d\n", SZ(ans));
	sort(ans.begin(), ans.end());
	for (auto t : ans)printf("%d ", t); printf("\n");
}
int main()
{
	int T; scanf("%d", &T);
	while(T--)
	{
		solve();
	}
	return 0;
}

https://codeforces.com/contest/1490/problem/F
F. Equalize the Array
题意
聚鲤鱼被赋予一个长度为n的数组a【】。如果存在一个数字C,则Polycarp认为数组很漂亮,这样数组中的每一个数都会发生0或C次。Polycarp想从数组a中删除一些元素,以使其美观。
思路:
思维正难则反,正着想去枚举删除最少的很难不如考虑还剩下几个;
参考代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define mp make_pair
using namespace std;
typedef pair<int, int> Pll;
#define x first
#define y second
void solve()
{
	int n; scanf("%d", &n);
	map<int, int> cnt;//记录次数
	for (int i = 1; i <= n; i++)
	{
		int tem; scanf("%d", &tem);
		cnt[tem]++;
	}
	vector<int> res;
	for (auto t : cnt) { res.push_back(t.second); }
	sort(res.begin(), res.end(), greater<int>());
	int ma = 0;//剩余多少数
	for (int i = 0; i < res.size(); i++)
		ma = max(ma, (i + 1) * res[i]);
	printf("%d\n", n - ma);
}
int main()
{
	int T; scanf("%d", &T);
	while (T--)
	{
		solve();
	}
	return 0;
}

https://codeforces.com/contest/1490/problem/G
G. Old Floppy Drive
题意:
给定个一环(长度为n)的数字每次从第1个数字开始,当走到数字n,又继续走到第1个位置。
思路:
前缀和加数学计算
参考代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define mp make_pair
#define SZ(a) (int)a.size()
using namespace std;
typedef pair<LL, int> Pll;
const LL INF = 1e13;
#define x first
#define y second
const int N = 2e5 + 10;
Pll pre_sum[N];
void solve()
{
	LL n, m; scanf("%lld%lld", &n, &m);
	vector<Pll> stk;
	LL ma = -INF;
	for (int i = 0; i < n; i++)
	{
		LL t; scanf("%lld", &t);
		if (!i) { pre_sum[i] = mp(t, i); }
		else { pre_sum[i].first = pre_sum[i - 1].first + t; pre_sum[i].second = i; }
		if (pre_sum[i].first > ma)
		{
			stk.push_back(pre_sum[i]);
			ma = pre_sum[i].first;
		}
	}
	LL d = pre_sum[n - 1].first;
	while (m--)
	{
		LL x; scanf("%lld", &x);
		int it = lower_bound(stk.begin(), stk.end(), mp(x, 0)) - stk.begin();
		if (it < SZ(stk)) { printf("%d ", stk[it].second); continue; }
		if (d <= 0) { printf("-1 "); continue; }
		int round_num = (x - ma) / d;
		if ((x - ma) % d != 0)round_num++;
		it = lower_bound(stk.begin(), stk.end(), mp(x - round_num * d, 0)) - stk.begin();
		printf("%lld ", (LL)stk[it].second +(LL) round_num * n);
	}
	printf("\n");
}
int main()
{
	int T; scanf("%d", &T);
	while (T--)
	{
		solve();
	}
	return 0;
}```

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值