Codeforces Round #673

Problems: https://codeforces.com/contest/1416 or https://www.luogu.com.cn/problem/list?keyword=CF1416


Solution


Div2 A.Copy-paste

签到题 一直用最小的加就好了
你可能会疑惑最小的就那么放掉会不会有点浪费
考虑最小和次小互相加的情形,更浪费了。

10min


Div2 B.Two Arrays

把一个 Array 分成两部分,要求[每部分里(相加等于 T 的数对个数)]的和最小。

这也是道签到题。值等于 (frac{T}{2}) 的对半分呐。
剩下的,小于的两两相加一定不等于,大于的两两相加一定不等于。
不要读错题就可以了。也不要犯傻排序了再去取个中间值再搞来搞去。

20min


A.k-Amazing Numbers

一个 Array 的 kAN 是指最小的,在该 Array 的所有长度为 k 的 Subsegments 里都出现的数
如果没有这种数就是 -1 。请 (O(nlog{n})) 计算 1AN ~ nAN

读完题就可以 Accepted
稍微模拟一下。然后我也不知道为啥我做了这么久。

30min


B.Make Them Equal

(1le i,jle n,quad 0le xle10^9)
每次操作:选择三元组 ((i,j,x)) 使 (a_i) 减去 (xcdot i) ,而 (a_j) 加上 (xcdot i)
请在 (3n) 操作内使长为 (n) 的序列 (a) 中每个元素相等。过程中不得出现负数。
(1le nle10^4,quad 1le a_ile10^5)
找到任意一种方案即可。请输出 (k) 的值 和 这 (k) 次操作。如果不能,请输出 -1

这题比较 interesting
(x) 可以自由选择。 (i)(j) 也可以自由选择,甚至可以一样(
很显然,假如 (i=1) 并且 (a_1) 足够大,那么可以随便挑一个 (a_i) 出来随便赋值
但是 (i>1) 就不行了。

从条件思考一下,为什么是 (3n)
假如已经满足 (i=1) 并且 (a_1) 足够大(应当为 (n) 的倍数),我们仍然需要 n 次操作让后面的数全部一样。
这个操作貌似不会改变 (sum a_i)
那完全可以把所有数挪到 (a_1) 再慢慢分配过去啊。同时可行性也能够直接判断了。

好吧。怎么挪?如果 (i|a_i) 那很简单
否则就得先凑到 (i|a_i)。从 (a_1) 那里拿过来凑就行了。
(a_1) 那里一定有吗?不一定
所以 (i)(2) 开始枚举到 (n) 就可以了。(a_ige0) 啊。

这样的话,最多就是凑+挪+挪回去,对于所有大于 1 的数最多操作 3 次
所以总的操作次数不超过 (3n-3)

我深刻地感觉我不能再依赖博客写题了 速度过慢

40min

Wa 了两三发。
务必注意一定要最后再把所有数从 1 分配过去
否则可能 1 的位置中途会出现负数。


C.XOR Inverse


D.Graph and Queries


E.Split


F.Showing Off


Code


Code: Div2A.

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iomanip>
#include<set>
#include<vector>
#include<map>
#include<queue>
using namespace std;
const int MAXN = 1005;
int T, n, k, Minn, id;
int a[MAXN], Ans;
int main()
{
	cin >> T;
	while (T--)
	{
		cin >> n >> k;
		Minn = 214748;
		Ans = 0;
		for (int i = 1; i <= n; ++i)
		{
			cin >> a[i];
			if (a[i] < Minn)
			{
				Minn = a[i];
				id = i;
			}
		}
		for (int i = 1; i <= n; ++i)
		{
			if (i != id) Ans += (k - a[i]) / Minn;
		}
		cout << Ans << endl;
	}
	return 0;
}

Code: Div2B.

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int MX = 1e5+10;
int t, N, T;
bool bel;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> t;
	while (t--)
	{
		cin >> N >> T; 
		for (int a, c = 0, i = 1; i <= N; ++i)
		{
			cin >> a; bel = 0;
			if ((a<<1) < T) bel = true;
			if ((a<<1) == T) bel = (c++)&1;
			cout << bel << ' ';
		} cout << endl;
	}
	return 0;
}

Code: A.

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN = 3e5 + 10;
int t, n;
int LastVis[MAXN];
int Filled[MAXN];
int Min[MAXN];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> t;
	while (t--)
	{
		cin >> n;
		for (int i = 1; i <= n; ++i) LastVis[i]=0, Min[i]=-1;
		for (int a, i = 1; i <= n; ++i)
		{
			cin >> a;
			Min[a] = max(Min[a], i-LastVis[a]);
			LastVis[a] = i;
			Filled[i] = 0;
		}
		for (int i = 1; i <= n; ++i)
		{
			Min[i] = max(Min[i], n + 1 - LastVis[i]);
		}
		for (int i = 1; i <= n; ++i)
		{
			if (Min[i]==-1) continue;
			if (!Filled[Min[i]]) Filled[Min[i]] = i;
		}
		for (int Laa = 0x3f3f3f3f, Lst = -1, i = 1; i <= n; ++i)
		{
			if (Filled[i] && Filled[i] < Laa) Lst = Filled[i], Laa = Filled[i];
			cout << Lst << " ";
		}
		cout << endl;
	}
	return 0;
}

Code: B.

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
const int MAXN = 1e4 + 10;
int t, n, tot = 0;
int a[MAXN], sm;
struct opt
{
    int i, j, x;
    opt(int a=0, int b=0, int c=0)
    {
        i=a; j=b; x=c;
    }
}grp[MAXN*3];
int main()
{
    cin >> t;
    while (t--)
    {
        tot = 0;
        cin >> n;
        cin >> a[1];
        sm = a[1];
        for (int i = 2; i <= n; ++i)
        {
        	cin >> a[i];
            sm += a[i];
        }
        if (sm%n)
        {
            puts("-1");
            continue;
        }
        sm /= n;
        for (int tmp, i = 2; i <= n; ++i)
        {
            tmp = a[i]/i;
            if (a[i]==tmp*i)
            {
                grp[++tot]=opt(i, 1, tmp);
            }
            else
            {
            	grp[++tot]=opt(1,i,(tmp+1)*i-a[i]);
            	grp[++tot]=opt(i,1,tmp+1);
            }
        }
        for (int i = 2; i <= n; ++i)
        {
        	grp[++tot]=opt(1,i,sm);
        }
        cout << tot << endl;
        for (int i = 1; i <= tot; ++i)
        {
        	cout << grp[i].i << " " << grp[i].j << " " << grp[i].x << endl;
        }
    }
    return 0;
}

Code: C.


Code: D.


Code: E.


Code: F.

原文地址:https://www.cnblogs.com/ccryolitecc/p/13771305.html