Educational Codeforces Round 104 (Rated for Div. 2) A~D

Educational Codeforces Round 104 (Rated for Div. 2) A~D

A. Arena

除去最少的那部分以外都对答案有贡献。

#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
int n, a[105];
int main()
{
	freopen("data.txt", "r", stdin);
	int t;
	cin >> t;
	while(t--)
	{
		cin >> n;
		int mmin = 10000, ans = 0;
		for(int i = 1; i <= n; i++)
		{
			cin >> a[i];
			mmin = min(mmin, a[i]);
		}
		for(int i = 1; i <= n; i++)
		{
			if(a[i] > mmin) ans++;
		}
		cout << ans << endl;
	}
}

B. Cat Cycle

见注释

#include <iostream>
#define int long long
using namespace std;
//观察可知,比如对于n=5的情况,双方第一次相遇的点是3,因此b先经过n / 2的时间到达2,然后直接到4,此时下一次相遇的点是1,因此b经过4,5,再直接跳到2.
//即1 2   4 5   2 3   5 1  3 4这样,实际上相当于每次花费n / 2的时间经过n / 2 + 1个点(说是经过实际上是为了方便讨论)。因此先求出走了多少个n / 2 + 1,然后单独加上剩下的即可
signed main()
{
	freopen("data.txt", "r", stdin);
	int t;
	cin >> t;
	while(t--)
	{
		int n, k;
		cin >> n >> k;
		if(n == 3)//n=3需要特判
		{
			if(k % 3 == 1) cout << 1 << endl;
			else if(k % 3 == 2) cout << 3 << endl;
			else cout << 2 << endl;
			continue;
		}
		if(n & 1)
		{ 
			int round = k / (n / 2), res = k % (n / 2);
			int tmp = (round * (n / 2 + 1)) % n;//走完round轮后所在的位置
			if(!tmp) tmp = n;//保证是在 1 2 3 ... n 1 2...里面循环
			if(!res) tmp--;//假设res是0,说明没有多余的,因此那一步跳的实际上不能算在最终走的点里面,比如1 2 4..这样,如果4没有走,那么最后停下的只能是在2,不会是3
			int ans = (tmp + res) % n;
			if(!ans) ans = n;//保证是在 1 2 3 ... n 1 2...里面循环
			cout << ans << endl;
		}
		else//n为偶数永远不会冲突
		{  
			cout << (k % n == 0 ? n : k % n) << endl;
		}
	}
}

C. Minimum Ties

构造。类似的cf构造题要秉承每行逐步推进循环的原则。

#include <iostream>
#include <cstring>
using namespace std;
int n, ans[105][105], pos[105];
int main()
{
	freopen("data.txt", "r", stdin);
	int t;
	cin >> t;
	while(t--)
	{
		cin >> n;
		memset(ans, 0, sizeof(ans));
		if(n == 2)
		{
			cout << 0 << endl;
			continue;
		}
		if((n - 1) & 1)//每队有一次平局,每行按照先11111再0再-1-1-1...,然后逐行挪动中心0的位置
		{
			for(int i = 1; i <= n; i++) 
			{
				for(int j = 1; j <= n; j++)
				{
					ans[i][j] = -1;
				}
			}
			for(int i = 1; i <= n; i++)
			{
				for(int j = 1; j <= n / 2 - 1; j++)
				{
					int tmp = (j + i) % n == 0 ? n : (j + i) % n;
					ans[i][tmp] = 1;
					if(j == n / 2 - 1)
					{
						tmp = (tmp + 1) % n;
						if(!tmp) tmp = n;
						ans[i][tmp] = 0;
					}
				}
			}
			for(int i = 1; i <= n - 1; i++)
			{
				for(int j = i + 1; j <= n; j++)
				{
					cout << ans[i][j] << ' ';
				}
			}
			cout << endl;
		}
		else//每队输赢一样多,同上类似,只不过没有0了
		{
			for(int i = 1; i <= n - 1; i++)
			{
				for(int j = 1; j <= (n - 1) / 2; j++)
				{
					int pos = (i + j) % n;;
					if(!pos) pos = n;
					ans[i][pos] = 1;
				}
			}
			for(int i = 1; i <= n - 1; i++)
			{
				for(int j = i + 1; j <= n; j++)
				{
					if(ans[i][j]) cout << 1 << ' ';
					else cout << -1 << ' ';
				}
			}
			cout << endl;
		}
	}
	return 0;
}

D. Pythagorean Triples

简单推一下然后枚举即可,详见注释。注意枚举的a的范围是根据a * a == 2 * b + 1, b <= n 来的,竟然能莽过233.

#include <iostream>
#include <cstring>
using namespace std;
int n;
// a * a == b + c   a * a + b * b == c * c 根据平方差公式 化简可得 c = b + 1, a * a = 2 * b + 1 枚举a即可
int main()
{
	freopen("data.txt", "r", stdin);
	int t;
	cin >> t;
	while(t--)
	{
		cin >> n;
		int ans = 0;
		for(int a = 3; a * a < 2 * n; a++)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
		{
			int tmp = a * a - 1;
			if(tmp & 1) continue;
			int b = tmp / 2, c = b + 1;
			if(a * a == b + c && a * a + b * b == c * c) ans++;
		}
		cout << ans << endl;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/lipoicyclic/p/14409030.html