打卡 Codeforces Round #599 (Div. 2)

A题
水题,贪心即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int k, n;
int a[1005];
int main()
{
	k = read();
	while (k--)
	{
		n = read();
		upd(i, 1, n)a[i] = read();
		sort(a + 1, a + 1 + n);
		int wid = 0;
		int hi = 0;
		hi = a[n]; wid = 1;
		int ans = 0;
		ans = min(hi, wid);
		dwd(i, n-1, 1)
		{
			hi = min(hi, a[i]);
			wid++;
			ans = max(ans,min(hi,wid));
		}
		printf("%d\n", ans);
	}
	return 0;
}

B题
继续暴力,有点冒泡排序的感觉。
只要每个字符的出现次数是偶数,那么一定可以通过某种交换使得两个字符串相等。暴力枚举和交换即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int k, n;
string s, t;
map<char, int>mp_s,mp_t,mp;
vector<int> pos[1005], pos_s[1005];
int main()
{
	k = read();
	while (k--)
	{
		n = read();
		mp_s.clear(); mp_t.clear(); mp.clear();
		upd(i, 0, n)pos[i].clear();
		cin >> s >> t;
		if (s.size() != t.size()) { cout << "no" << endl; continue; }
		int cnt = 0;
		for (auto p : s)mp_s[p]++,mp[p]++,pos_s[p].push_back(cnt++);
		cnt = 0;
		for (auto p : t)mp_t[p]++,pos[p].push_back(cnt++),mp[p]++;
		bool flag = 0;
		for (auto p : mp)if (p.second % 2)flag = 1;
		if (flag) { printf("NO\n"); continue; }
		vector<pir>ans;
		up(i, 0, s.size())
		{
			if (s[i] != t[i])
			{
				bool flag = 0;
				up(j, i+1, t.size())
				{
					if (t[j] == s[i])
					{
						swap(s[i + 1], t[j]);
						swap(s[i + 1], t[i]);
						ans.push_back(make_pair(i + 2, j+1));
						ans.push_back(make_pair(i + 2, i+1));
						flag = 1;
						break;
					}
				}
				if (!flag)
				{
					up(j, i+1, s.size())
					{
						if (s[j] == s[i])
						{
							swap(s[j], t[i]);
							ans.push_back(make_pair(j+1, i+1));
							break;
						}
					}
				}
			}
		}
		printf("YES\n");
		printf("%d\n", ans.size());
		//cout << s << " " << t << endl;
		for (auto k : ans)printf("%d %d\n", k.first, k.second);
	}
	return 0;
}

C题
我们首先看有两个数字互质的情况。
由完全剩余系可以知道,如果a,b两个数字互质,a*1,a*2,a*3,...a*(b-1),a*b 模上b,可以取到1~b-1的一个permutation。
即,我们假设x染成颜色1,x+a,x+2a,x+3a....都将成为颜色1,由上述定理可知,(x+1)+b,(x+1)+b*2....肯定会由c,c=x+m*a,c=(x+1)+n*b,所以x和x+1一定会被染色成一个颜色。
我们对n进行唯一分解定理,如果有两个质数,那么答案为1。
如果只有一个质数,答案为该质数。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
ll n;
vector<ll>vec;
int	main() {
 
	n = read();
	if (n == 1)
	{
		printf("%d\n", 1);
		return 0;
	}
	for (ll i = 2; i*i <= n; i++)
	{
		while (!(n%i))
		{
			while (!(n%i))n /= i;
			vec.push_back(i);
		}	
	}
	if (n > 1)vec.push_back(n);
	if (vec.size() > 1)
	{
		printf("%d\n", 1);
	}
	else
	{
		printf("%lld\n", vec.front());
	}
	return 0;
}

D题
还是暴力。
相当于判断,通过代价为零的边,能有多少个连通块,答案为连通块的数目减一。
因为是个完全图,每一个点必然和其他所有点有边,我们把能通过0的边连在一起的点缩成一块。每一个块之间,将必然会使用代价为1的边相连,所以代价为快数-1。
考虑暴力dfs,开vis数组,保证每一个节点只会被访问一次。
每一次dfs考虑没有被vis过的,和不会权值1的边相连的点。
要注意优化,单纯来看时间复杂度是nlogn(用map来搜索了的所有有log)
但是块数如果太多,因为每一次访问都需要遍历所有n个点,将会变成n^2
故再开一个set,访问过的点从set里面删除,每一次脂肪问set里面的点。
这样复杂度就将变成,sigma size(块)*logn
(当然也可以理解成为树就是n个点,n-1条边,所以最后需要块数-1条边)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
set<int>s[N],init_s;
int n, m;
int height[N];
int pr[N];
int vis[N];
void init()
{
	upd(i, 0, n)
		height[i] = 1, pr[i] = i;
	upd(i, 1, n)init_s.insert(i);
}
int find_pr(int x)
{
	return pr[x] == x ? x : pr[x] = find_pr(pr[x]);
}
void unit(int x, int y)
{
	x = find_pr(x);
	y = find_pr(y);
	if (x == y)return;
	if (height[x] < height[y])
		swap(x, y);
	height[x] += height[y];
	pr[y] = x;
}
void dfs(int u)
{
	vis[u] = 1;
	vector<int>vec;
	for (auto p : init_s)
	{
		if(s[u].find(p)==s[u].end())
			vec.push_back(p);
	}
	for (auto p : vec)init_s.erase(p);
	for(auto p:vec) {
		if (vis[p])continue;
		dfs(p);
		unit(u, p);
	}
}
int main()
{
	n = read(), m = read();
	int u, v;
	up(i, 0, m)
	{
		u = read(), v = read();
		s[u].insert(v);
		s[v].insert(u);
	}
	init();
	int ans = 0;
	upd(i, 1, n)
	{
		if (!vis[i])
		{
			init_s.erase(i);
			dfs(i);
		}
	}
	int nums = 0;
	upd(i, 1, n)
	{
		if (pr[i] == i)nums++;
	}
	printf("%d\n", nums - 1);
}
posted @ 2019-12-21 18:24  LORDXX  阅读(96)  评论(0编辑  收藏  举报