首页 > 其他分享 >Codeforces Round #599 (Div. 2) 题解

Codeforces Round #599 (Div. 2) 题解

时间:2023-05-31 10:02:45浏览次数:53  
标签:typedef 599 题解 ll long int Div mx define


题目链接:https://codeforces.com/contest/1243

 

A - Maximum Square

水题不说了

#include <bits/stdc++.h>
using namespace std;
const int mx = 1e5 + 50;
typedef long long ll;
int n; 
int a[mx];
int main() {
	int t;
	scanf("%d",&t);
	while (t--) {
		scanf("%d",&n);
		for (int i=1;i<=n;i++) {
			scanf("%d",a+i);
		}
		sort(a+1,a+1+n);
		int mi = 1e7;
		int ans = -1;
		for (int i=n;i>=1;i--) {
			mi = min(mi,a[i]);
			ans = max(ans,min(mi,n-i+1));
		}
		printf("%d\n",ans);
	} 
	return 0;
}

B2 - Character Swap (Hard Version)

固定第一个字符串,然后第二个字符串的当前位置要和第一个串一样,至多用后面的字符换2次就好了,所以是2*n次

#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
const int mx = 100 + 50;
typedef long long ll;
typedef pair<int,int> pa;
int n; 
char s1[mx],s2[mx];
int vis[mx];
pa ans[mx];
int siz;
pa find_pos(int x) {
	for (int i=x+1;i<=n;i++) 
		if (s1[i]==s1[x])
			return pa(0,i);
		else if (s2[i]==s1[x])
			return pa(1,i);
}
bool solve() {
	for (int i=0;i<26;i++) if(vis[i]%2!=0)
		return 0;
	for (int i=1;i<=n;i++) {
		if (s1[i]==s2[i]) continue;
		pa now = find_pos(i);
		if (now.fi == 0) {
			swap(s2[i],s1[now.se]);
			ans[siz++] = pa(now.se,i);
		} else {
			swap(s1[n],s2[now.se]);
			swap(s1[n],s2[i]);
			ans[siz++] = pa(n,now.se);
			ans[siz++] = pa(n,i);
		}
	}
	return 1;
}
int main() {
	int t;
	scanf("%d",&t);
	while (t--) {
		scanf("%d",&n);
		scanf("%s%s",s1+1,s2+1);
		siz = 0;
		memset(vis,0,sizeof(vis));
		for (int i=1;s1[i];i++)
			vis[s1[i]-'a']++;
		for (int i=1;s2[i];i++)
			vis[s2[i]-'a']++;
		if(!solve()) puts("No");
		else {
			printf("Yes\n%d\n",siz);
			for (int i=0;i<siz;i++)
				printf("%d %d\n",ans[i].fi,ans[i].se);
		}
	} 
	return 0;
}

C - Tile Painting

超过一个质数肯定都一样,因为肯定有x使得a*p1 - b*p2 == 1,所以i和i-1颜色一样。

然后一个质数答案就是那个质数了

#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
const int mx = 1e6 + 10;
typedef long long ll;
typedef pair<int,int> pa;
ll n; 
vector <int> pri;
bool vis[mx];
void init() {
	for (int i=2;i<mx;i++) {
		if (!vis[i]) pri.push_back(i);
		for (int j : pri) {
			if (j*i >= mx) break;
			vis[i*j] = 1;
			if (i%j==0) break;
		}
	}
}
int main() {
	init();
	ll n;
	int cnt = 0;
	scanf("%lld",&n);
	ll ans = n;
	for (int i:pri) {
		if (i >= n) break;
		if (n % i == 0) {
			if (cnt) return 0*puts("1");
			cnt = i;
			ans = cnt;
		}
		while (n % i == 0) n /= i;
	}	
	if (cnt && n != 1) return 0*puts("1");
	printf("%lld\n",ans);
	return 0;
}

D - 0-1 MST

暴力

#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
const int mx = 1e5 + 10;
typedef long long ll;
typedef pair<int,int> pa;
int n,m;
map <int,int> mp[mx];
set <int> st,nt;
void dfs(int u) {
	nt.clear();
	vector <int> g;
	for (int v:st) {
		if (!mp[u][v]) 
			g.push_back(v);
		else
			nt.insert(v);
	}
	st = nt;
	for (int v:g)
		dfs(v);
}
int main() {
	scanf("%d%d",&n,&m);
	int u,v;
	for (int i=0;i<m;i++) {
		scanf("%d%d",&u,&v);
		mp[u][v] = 1;
		mp[v][u] = 1;
	}
	for (int i=1;i<=n;i++)
		st.insert(i);
	int ans = 0;
	while (!st.empty()) {
		int now = *st.begin();
		st.erase(st.begin());
		dfs(now);
		ans++;
	}
	printf("%d\n",ans-1);
	return 0;
}

E - Sum Balance

连下边,然后跑一跑环就ok了,注意是简单环

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pa;
typedef long long ll;
const int mx = 100 + 10;
int m;
ll num[mx];
vector <int> g[mx],r[1<<18];
map <ll,int> mp;
map <int,int> mvis;
stack <int> sta;
pa s[mx*mx];
int vis[1<<18],siz;
bool vis2[1<<18];
pa ans[mx];
ll reg;
int get_ed(int x) {
	ll y = reg - num[mp[x]] + x;
	return mp.count(y)? y : -1; 
}
void full (int u) {
	int y = 0;
	bool mark[20];
	memset(mark,0,sizeof(mark));
	while (sta.top() != u){
		int v = sta.top();
		sta.pop();
		if (mark[mp[v]]) return ;
		mark[mp[v]] = 1;
		y |= 1<<(mp[v]-1);
	}
	if (mark[mp[u]]) return ;
	y |= 1<<(mp[u]-1);
	if (vis2[y]) return ;
	vis2[y] = 1;
	s[siz++] = pa(y,u);
}
void dfs(int u) {
	if (mvis[u] == 2) return ;
	if (mvis[u] == 1) {
		full(u);
		return ;
	}
	mvis[u] = 1;
	sta.push(u);
	int v = get_ed(u);
	if (v != -1) dfs(v);
	mvis[u] = 2;
}
int main() {
	ll sum = 0;
	int cnt = 0;
	scanf("%d",&m);
	for (int i=1;i<=m;i++) {
		int c,u;
		scanf("%d",&c);
		for (int j=0;j<c;j++) {
			scanf("%d",&u);
			g[i].push_back(u);
			mp[u] = i;
			num[i] += u,sum += u;
		}
	}
	if (sum % m) return 0*puts("No");
	reg = sum / m;
	for (int i=1;i<=m;i++) {
		for (int j:g[i]) if (!mvis[j])
			dfs(j);
	}
	vis[0] = 1;
	for (int i=1;i<(1<<m);i++) {
		for (int j=0;j<siz;j++) if((i&s[j].fi) == s[j].fi)
		{
			vis[i] = vis[i^s[j].fi];
			if (vis[i]) {
				r[i].push_back(s[j].se);
				r[i].insert(r[i].end(),r[i^s[j].fi].begin(),r[i^s[j].fi].end());
				break;
			}
		}
	}
	int bv = (1<<m) - 1;
	if (r[bv].size()) {
		puts("Yes");
		for (int i:r[bv]) {
			int j = i;
			do {
				int nj = get_ed(j);
				int np = mp[j];
				ans[mp[nj]] = pa(nj,np);
				swap(j,nj);
			} while (j != i);
		}
		for (int i=1;i<=m;i++)
			printf("%d %d\n",ans[i].fi,ans[i].se);
	} else puts("No");
    return 0;
}

 

标签:typedef,599,题解,ll,long,int,Div,mx,define
From: https://blog.51cto.com/u_12468613/6384518

相关文章

  • Codeforces #564 (Div. 2) C. Nauuo and Cards[贪心]
    题目链接:http://codeforces.com/contest/1173/problem/C 解题思路:很明显总的抽卡次数是不会超过2*n的。然后我们再将情况分成两种:1.编号1的卡片已经在里面了,并且最底部已经形成了一个1~x的连续的卡片,而且之后x+1,x+2都可以来得及补上,在这种情况下抽卡次数肯定就不会超过n了。2.......
  • Codeforces #564 (Div. 2) D. Nauuo and Circle[树形DP]
    题目链接:http://codeforces.com/contest/1173/problem/D 解题思路:首先得知道按照圆周顺序的话,那么一颗子树必须存放在连续的一段区间里面,现在我们假设根节点是1,那么一颗为u做根节点的子树他的方案数就是各个儿子的方案数的乘积最后再乘以儿子个数+1(u节点本身)的排列方案数。所......
  • 题解 AT_nikkei2019ex_e【コラッツ問題】
    啥玩意,诈骗题还能这么诈骗。\(f(X)\)就是角谷猜想(冰雹猜想)所需的步数。根据角谷猜想,定义函数\(g\):\[g(X)=\begin{cases}\frac{X}{2},&2\midX\\3X+1,&2\nmidX\end{cases}\]则显然有\(f(g(X))=f(X)-1\)。样例二已经给出了\(f(X)=1000\)的解\(X=1789997546303\),而\(P......
  • Educational Codeforces Round 149 (Rated for Div. 2)
    A.GrasshopperonaLine#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongvoidsolve(){intx,k;cin>>x>>k;if(x%k==0){cout<<"2\n"<<x-1<<"&......
  • P9376 题解
    首先考虑怎么暴力。考虑把每个数进行\(B\)进制分解,然后我们惊奇的发现这两个操作就是把最低位去掉和往最低位后面插入一个数。然后我们顺藤摸瓜,把每个数的分解扔到Trie树上,我们发现我们要找到一个节点,使得所有单词节点到其的距离之和最短,答案就是这个最短距离。这里直接考......
  • CODE FESTIVAL 2016 qual B E 题解
    以下\(\Sigma\)为字符集。首先单次询问\(O(|\Sigma||S|)\)的暴力是显然的:建出trie树,然后每次把对应的字符串在上边扫,加上对应位置比它小的子树的大小。然后接下来有两种方法。正解首先在线大概是没什么前途的,考虑离线,建出trie树之后在上边dfs,处理挂在每个节点上的询......
  • leetcode 728. Self Dividing Numbers
    Aself-dividingnumberisanumberthatisdivisiblebyeverydigititcontains.Forexample,128isaself-dividingnumberbecause128%1==0,128%2==0,and128%8==0.Also,aself-dividingnumberisnotallowedtocontainthedigitzero.Givenal......
  • CF1398E Two Types of Spells 题解 set
    题目链接:https://codeforces.com/problemset/problem/1398/E题目大意你有一个集合,初始为空。有两种类型的元素,一种是普通元素,一种是强化元素,两种元素都有一个数值。有\(n\)次操作,每次操作会往集合中加入一个元素或者删除一个元素。每次操作后,你都需要确定集合中元素的一个......
  • 第十四届蓝桥杯大赛青少组全国总决赛初级组C++C++题解
    第十四届蓝桥杯大赛青少组全国总决赛初级组\(C++\)题解第一题给定一个十进制正整数\(N(1≤N≤10^9)\),请从小到大输出\(1\)~\(N\)之间(含\(1\)和\(N\))所有满足以下要求的数:这个数转换为八进制后是一个回文数;这个数是一个平方数。例如:\(N=20\),在\(1\)~\(20\)之间满足要求......
  • Codeforces Round 875 (Div. 2) A-D
    A.TwinPermutations题意:给出一个由[1,2,...,n]组成的数组a,构造另一个由[1,2,...,n]组成的数组b,使得a[1]+b[1]<=a[2]+b[2]<=...<=a[n]+b[n]Solution可以想到只要让他们全为n+1就行了,这样是一定有解的voidsolve(){ intn;cin>>n; for(inti=1;i<=n;i++) { cin>>a[i]; ......