首页 > 其他分享 >CF1162 Codeforces Round 557 (Div. 2) [based on Forethought Future Cup - Final Round]

CF1162 Codeforces Round 557 (Div. 2) [based on Forethought Future Cup - Final Round]

时间:2023-09-27 22:22:12浏览次数:33  
标签:return Cup int seg 权值 based include Round const

CF1162A Zoning Restrictions Again

每个位置越高越好,暴力模拟即可。


#include<iostream>
#include<cstdio>
using namespace std;
const int N=55;
int n,h,m;
int a[N];
int main()
{
	scanf("%d%d%d",&n,&h,&m);
	for(int i=1;i<=n;i++)
		a[i]=h;
	for(int i=1;i<=m;i++)
	{
		int l,r,x;
		scanf("%d%d%d",&l,&r,&x);
		for(int j=l;j<=r;j++)
			a[j]=min(a[j],x);
	}
	long long ans=0;
	for(int i=1;i<=n;i++)
		ans+=1LL*a[i]*a[i];
	printf("%lld",ans);
	return 0;
}

CF1162B Double Matrix

可以发现,最后两个矩阵的 \((i,j)\) 的数分别为 \(\min(a_{i,j},b_{i,j})\),\(\max(a_{i,j},b_{i,j})\) 会尽可能优,其他情况不会比这种情况更优,判断一下是否合法即可。


#include<iostream>
#include<cstdio>
using namespace std;
const int N=55;
int n,m;
int a[N][N],b[N][N];
int c[N][N],d[N][N];
bool check(int s[N][N])
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(s[i][j]<=s[i-1][j]||s[i][j]<=s[i][j-1]) return false;
	return true;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&b[i][j]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			c[i][j]=min(a[i][j],b[i][j]),d[i][j]=max(a[i][j],b[i][j]);
	if(check(c)&&check(d)) printf("Possible");
	else printf("Impossible");
	return 0;
}

CF1162C Hide and Seek

枚举代币在哪个位置,判一下向左移,不动,向右移是否合法即可。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100005;
int n,k;
int a[N];
int Max[N],Min[N];
int main()
{
	scanf("%d%d",&n,&k);
	memset(Min,63,sizeof(Min));
	for(int i=1;i<=k;i++)
	{
		scanf("%d",&a[i]);
		Max[a[i]]=max(Max[a[i]],i);
		Min[a[i]]=min(Min[a[i]],i);
	}	
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(i-1>=1&&Min[i]>Max[i-1]) ans++;
		if(i+1<=n&&Min[i]>Max[i+1]) ans++;
		if(Min[i]>Max[i]) ans++;
	}
	printf("%d",ans);
	return 0;
}

CF1162D Chladni Figure

枚举 \(n\) 的因子 \(d\),判断 \(k=d\) 的时候是否合法即可。


#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=200005;
int n,m;
pair<int,int>seg[N];
pair<int,int>b[N];
int tot;
bool check(int k)
{
	tot=0;
	for(int i=1;i<=m;i++)
	{
		pair<int,int>nxt={(seg[i].first+k)%n==0?n:(seg[i].first+k)%n,(seg[i].second+k)%n==0?n:(seg[i].second+k)%n};
		if(nxt.first>nxt.second) swap(nxt.first,nxt.second);
		b[++tot]=nxt;
	}
	sort(b+1,b+tot+1);
	for(int i=1;i<=m;i++)
		if(seg[i]!=b[i]) return false;
	return true;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		if(a>b) swap(a,b);
		seg[i]={a,b};
	}
	sort(seg+1,seg+m+1);
	if(check(1))
	{
		printf("Yes");
		return 0;
	}
	for(int i=2;i<=sqrt(n);i++)
		if(n%i==0)
		{
			if(check(i)||check(n/i))
			{
				printf("Yes");
				return 0;
			}
		}
	printf("No");
	return 0;
}

CF1162E Thanos Nim

最后的获胜条件等价于 \(0\) 的堆数要 \(> \frac{2}{n}\)。

如果最小堆的数量 \(> \frac{2}{n}\),先手一定会取到某个最小堆,最小堆的数量会 \(\leq \frac{2}{n}\),后手可以将最小堆的数量 \(> \frac{2}{n}\),一直循环直到后手将 \(0\) 的堆数 \(> \frac{2}{n}\)。

那么可以推出:

如果最小堆的数量 \(\leq \frac{n}{2}\),则先手必胜,否则后手必胜。


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=55;
int n;
int a[N];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	int m=*min_element(a+1,a+n+1);
	int cnt=0;
	for(int i=1;i<=n;i++)
		if(a[i]==m) cnt++;
	if(cnt>n/2) printf("Bob");
	else printf("Alice");
	return 0;
}

CF1162F Palindrome XOR

可以发现,\(b\) 的二进制位数一定等于 \(m\),考虑枚举 \(a\) 的位数 \(n\)。

问题可以转化成一些限制,表示某些位置要和某些位置的数相等或不同。

考虑建图,边权为 \(1\) 的边表示这两个点的权值不同,边权为 \(0\) 的边表示这两个点的权值相同。方案数即为原图的染色方案。

对于一个二进制位,我们可以将其拆成两个点,表示这个点取 \(0\) 或 \(1\)。再用两个点 \(0,1\) 表示取 \(0\) 和 \(1\) 的点,在这两个点之间连一条权值为 \(1\) 的边。

对于某个位置 \(i\),它的权值已经确定,就将它连向它的权值一条权值为 \(0\) 的边。

对于 \(s_i=1\),可以在 \(a_i\) 和 \(b_i\) 之间连权值为 \(1\) 的边;\(s_i=0\) 可以在 \(a_i\) 和 \(b_i\) 之间连权值为 \(0\) 的边。

回文的限制也连一下权值为 \(0\) 的边。

可以将权值为 \(0\) 的边缩起来,然后二分图染色判断一下是否合法。如果合法,令 \(cnt\) 为图中的联通块数,这种情况下的答案为 \(2^{cnt-1}\)。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N=2005;
const int MOD=998244353;
long long pw[N];
int n;
char s[N];
int fa[N];
int getf(int v)
{
	if(v==fa[v]) return v;
	else return fa[v]=getf(fa[v]);
}
void merge(int u,int v)
{
	int f1=getf(u),f2=getf(v);
	if(f1!=f2) fa[f2]=f1;
	return;
}
int ida[N],idb[N];
int id[2],tot;
vector<int>G[N];
int col[N];
bool flag;
void dfs(int u)
{
	for(int v:G[u])
	{
		if(col[v]!=-1)
		{
			if(col[v]==col[u])
			{
				flag=true;
				return;
			}
			else continue;
		}
		col[v]=col[u]^1;
		dfs(v);
		if(flag) return;
	}
	return;
}
int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	id[0]=++tot;
	id[1]=++tot;
	for(int i=1;i<=n;i++)
		ida[i]=++tot,idb[i]=++tot;
	pw[0]=1;
	for(int i=1;i<=tot;i++)
		pw[i]=pw[i-1]*2%MOD;
	long long ans=0;
	for(int len=2;len<=n;len++)
	{
		for(int i=1;i<=tot;i++)
			fa[i]=i,col[i]=-1,G[i].clear();
		merge(ida[len],id[1]);
		merge(idb[1],id[1]);
		for(int i=1;i<len;i++)
			merge(ida[i],id[0]);
		for(int i=len;i<=n;i++)
			merge(ida[i],ida[n-(i-len+1)+1]);
		for(int i=1;i<=n;i++)
		{
			merge(idb[i],idb[n-i+1]);
			if(s[i]=='0') merge(ida[i],idb[i]);
		}
		G[getf(id[0])].emplace_back(getf(id[1])),G[getf(id[1])].emplace_back(getf(id[0]));
		for(int i=1;i<=n;i++)
			if(s[i]=='1') G[getf(ida[i])].emplace_back(getf(idb[i])),G[getf(idb[i])].emplace_back(getf(ida[i]));
		flag=false;
		int num=0;
		for(int i=1;i<=tot;i++)
			if(getf(i)==i&&col[i]==-1)
			{
				col[i]=0;
				dfs(i);
				if(flag) break;
				num++;
			}
		if(flag) continue;
		ans=(ans+pw[num-1])%MOD;
	}
	printf("%lld",ans);
	return 0;
}

标签:return,Cup,int,seg,权值,based,include,Round,const
From: https://www.cnblogs.com/zhou-jk/p/17734513.html

相关文章

  • Codeforces Round 900 (Div. 3) - A B C D E
    目录A.HowMuchDoesDaytonaCost?B.AleksaandStackA.HowMuchDoesDaytonaCost?判断数k包不包含在数组里面即可B.AleksaandStack选定初始数为2,3,后面的遍历法二:全奇数即可,因为奇数+奇数=偶数,奇数x3=奇数,......
  • [题解] Codeforces Round 900(Div.3) E~F
    CodeforcesRound900(Div.3)E~FE.Iva&Pav因为按位与的结果不会随着越多数字的增加而增加,因此我们可以利用这个性质二分出右端点,只需要一个可以查询区间的数据结构即可。或者是按位考虑第\(i\)个数字的第\(k\)位,后缀最近的\(0\)的位置,按位考虑也可以。但是这题使用二分......
  • 2023.9.27 LGJ Round
    A已知一个字符串\(n\le1e3\)中的若干信息,:\((x,y,z)\)表示\(x\)后缀和\(y\)后缀的\(\text{LCP}=z\).求满足条件的字典序最小的字符串。已知\(a_{x+i}=a_{y+i}(i<z)\),考虑维护并查集,一定相同的在一个集合。然后要处理的是\(a_{x+z}\neqa_{y+z}\)。从前往后填即可。......
  • B. Amr and Pins( Codeforces Round #287 (Div. 2))
    #include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>intmain(){doubler,x1,y1,x2,y2;while(scanf("%lf%lf%lf%lf%lf",&r,&x1,&y1,&x2,&y2)!=EOF){doubleaa=sq......
  • C. Anya and Ghosts(Codeforces Round #288 (Div. 2))
    #include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<stdlib.h>usingnamespacestd;structnode{intx;inty;}q[3010];inta[3001];intn,m,k;intmain(){while(scanf("......
  • C. Anya and Ghosts( Codeforces Round #288 (Div. 2))
    #include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<stdlib.h>usingnamespacestd;structnode{intx;inty;}q[3010];inta[3001];intn,m,k;intmain(){while(scanf("......
  • [892] Change the background color of a table in a Word document
    ref:python-docxChangingTableCellBackgroundColor.TochangethebackgroundcolorofatableinaWorddocumentusingPython,youcanusethepython-docxlibrary,whichallowsyoutocreateandmodifyWorddocumentsprogrammatically.Here'show......
  • Codeforces Round 900 (Div. 3)
    昨天晚上生病,没比(血亏)A:就是看k有没有在序列里B:随便放一个大的号码然后加i,应该就可以过了C:就是我们最少要拿k*(k+1)/2,最多可以拿k*(n+n-k+1)/2。啊,你问我怎么证明在这两个值里就一定可以拿到(当然是猜的!!)D:让f[x]表示当前出了多少次。然后就没个k看l[i],r[i]和j有没......
  • Codeforces Round 742 Div2 A-D题解
    CodeforcesRound742Div2A-D题解A.DominoDisaster这题就是说给出一些2x1tile,然后给出2xn的第一行构造,问第二行这个刚开始想着是啥dp,一看那么多人过了果断改思路,发现这题就是个模拟题,就是把U换成D,D换成U,L和R不影响,然后输出就行了代码#include<bits/stdc++.h>using......
  • 【教程】VIM的使用第九章-成对编辑的插件vim-surround以及收尾一些好用的常用插件
    书接上回,我们继续讲剩下的一些插件内容,以及对剩余的一些内容进行补充,这也就是vim的教程最后一章了~大家可以脱离苦海了~~但是后期想用好vim还是需要大家积极的练习多用。插件vim-surround在日常开发中我们需要成对的修改,比如一次性将单引号改为双引号,就可以用到这个插件了地址......