首页 > 其他分享 >Keyence Programming Contest 2020

Keyence Programming Contest 2020

时间:2023-09-27 19:24:37浏览次数:46  
标签:const int Keyence Programming long 2020 移除 include MOD

A - Painting


每次取 \(H,W\) 中较大者涂就是了,输出 \(\lceil \frac{n}{\max(H,W)}\rceil\)。


代码:

#include<iostream>
#include<cstdio>
using namespace std;
int h,w,n;
int main()
{
	scanf("%d%d%d",&h,&w,&n);
	if(h<w) swap(h,w);
	printf("%d",(n+h-1)/h);
	return 0;
}

B - Robot Arms

考虑贪心,按照左端点从大到小排序,然后每次贪心的如果能将当前线段加入答案就加入答案,因为如果选后面的线段的话左端点只会更小,答案不会更优。


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
const int INF=1061109567;
int n;
struct Node
{
	int l,r;
}a[N];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int x,l;
		scanf("%d%d",&x,&l);
		a[i].l=x-l,a[i].r=x+l;
	}
	sort(a+1,a+n+1,[=](const Node &a,const Node &b){return a.l==b.l?a.r<b.r:a.l>b.l;});
	int ans=0,now=INF+INF;
	for(int i=1;i<=n;i++)
		if(a[i].r<=now) ans++,now=min(now,a[i].l);
	printf("%d",ans);
	return 0;
}

C - Subarray Sum

构造连续的 \(k\) 个 \(S\),其他的都填 \(10^9\),当 \(S=10^9\) 时特判一下就好了。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100005;
int n,k,s;
int main()
{
	scanf("%d%d%d",&n,&k,&s);
	for(int i=1;i<=k;i++)
		printf("%d ",s);
	for(int i=1;i<=n-k;i++)
		printf("%d ",s==1000000000?1000000000-1:1000000000); 
	return 0;
}

D - Swap and Flip

可以发现,对于一个点 \(i\),如果它最后到了 \(p_i\),那么它为正面的条件为 \(2|i-p_i\),否则为反面。

考虑状压 DP,令 \(f_{s,i}\) 表示当前已经确定了结果序列前 \(t\) 个(\(t\) 表示 \(s\) 二进制中 \(1\) 的个数)放 \(s\) 这个集合的数,最后一个放的点为 \(i\) 的最小步数。可以知道当前放的点的位置为 \(t\) 这个位置,就可以判断出当前点是否为正面。枚举上一个放的位置 \(j\),每次将新产生的逆序对加入贡献就好了。


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=20;
const int INF=1061109567;
int n;
int a[N],b[N];
int f[1<<N][N];
int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
		scanf("%d",&a[i]);
	for(int i=0;i<n;i++)
		scanf("%d",&b[i]);
	memset(f,63,sizeof(f));
	f[0][0]=0;
	for(int s=1;s<(1<<n);s++)
	{
		int t=__builtin_popcount(s);
		for(int i=0;i<n;i++)
			if(s&(1<<i))
			{
				int v=(abs(t-(i+1))&1)?b[i]:a[i];
				int num=0;
				for(int j=i+1;j<n;j++)
					if(s&(1<<j)) num++;
				for(int j=0;j<n;j++)
					if((s^(1<<i))==0)
					{
						f[s][i]=min(f[s][i],f[s^(1<<i)][j]+num);
						continue;
					}
					else if((s^(1<<i))&(1<<j))
					{
						int vt=(abs(t-1-(j+1))&1)?b[j]:a[j];
						if(vt<=v) f[s][i]=min(f[s][i],f[s^(1<<i)][j]+num);
					}
			}
	}
	int ans=INF;
	for(int i=0;i<n;i++)
		ans=min(ans,f[(1<<n)-1][i]);
	if(ans>=INF) printf("-1");
	else printf("%d",ans);
	return 0;
}

E - Bichromization

可以发现,对于有解的情况,我们肯定可以将每个 \(d_i\) 对应一条边的权值。

考虑一种匹配的过程,如果对于一个点 \(u\),如果它与另一个点 \(v\) 匹配,点 \(v\) 可以选择与 \(u\) 配对或者选另一个点配对,这种情况下肯定有 \(d_v\ge d_u\)。

考虑贪心,每次按照 \(d_i\) 从小到大枚举。对于每个点 \(u\),如果它有与其相邻的 \(d_u=d_v\),那么就将两个点匹配;否则找一个已经染过色的点匹配,如果找不到的话说明无解。


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int N=100005;
int n,m;
int d[N];
int id[N];
vector<pair<int,int> >G[N];
int col[N];
int ans[N<<1];
void draw(int u)
{
	if(col[u]) return;
	for(auto [v,i]:G[u])
		if(col[v]==0&&d[u]==d[v])
		{
			col[u]=1,col[v]=2;
			ans[i]=d[u];
			return;
		}
	for(auto [v,i]:G[u])
		if(col[v])
		{
			col[u]=col[v]==1?2:1;
			ans[i]=d[u];
			return;
		}
	printf("-1");
	exit(0);
	return;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&d[i]),id[i]=i;
	sort(id+1,id+n+1,[=](const int &x,const int &y){return d[x]<d[y];});
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		G[x].push_back(make_pair(y,i));
		G[y].push_back(make_pair(x,i));
	}
	for(int i=1;i<=n;i++)
		draw(id[i]);
	for(int i=1;i<=m;i++)
		if(!ans[i]) ans[i]=1e9;
	for(int i=1;i<=n;i++)
		if(col[i]==1) printf("W");
		else if(col[i]==2) printf("B");
	printf("\n");
	for(int i=1;i<=m;i++)
		printf("%d\n",ans[i]);
	return 0;
}

F - Monochromization

考虑一个最终的矩阵,我们考虑从后往前操作。

我们称一行或一列为可移除的当且仅当这行或这列的颜色相同,我们可以定义两种与题意中等价的操作:

  • 将所有可移除行删除(剩下的行形成一个新的矩阵);
  • 将所有可移除列删除(剩下的列形成一个新的矩阵)。

可以发现,我们每次交替的进行两种操作,一个最终的矩形所对应的操作序列是唯一的。我们只需要计算合法的操作序列即可。

可以发现,我们并不需要考虑具体的矩形长什么样子,我们只需要考虑它的行数和列数还有每次移除的颜色种类。

令 \(f_{i,j,k}\) 表示上一次移除的是行,还有 \(i\) 行 \(j\) 列没有移除,上次移除的行有 \(k\) 种不同的颜色;\(g_{i,j,k}\) 表示上一次移除的是列,还有 \(i\) 行 \(j\) 列没有移除,上次移除的列有 \(k\) 种不同的颜色。

可以发现,如果上次移除的列都是黑色,我们当前移除了黑色的行,那么我们显然可以在上一次删行时把这一行删掉。所以我们当前移除的行必然都是白色的。

那么我们可以得出转移:

\((2\cdot f_{i,j,2}+f_{i,j,1})\cdot C(i,i-k)\to g_{k,j,1} (k< i)\)

\(f_{i,j,2}\cdot C(i,i-k)\cdot (2^{i-k}-2)\to g_{k,j,1} (k< i)\)

DP 完成后,枚举最后保留的行和列,合法的条件即为是保留的行和列组成的矩阵不存在可移除行和可移除列,需要除以两个组合数。

实现时注意边界问题就可以了。


#include<iostream>
#include<cstdio>
using namespace std;
const int N=15;
const int MOD=998244353;
int n,m;
long long ksm(long long a,long long b)
{
	long long res=1;
	while(b)
	{
		if(b&1) res=res*a%MOD;
		a=a*a%MOD,b>>=1;
	}
	return res;
}
long long fac[N],inv[N];
long long Pw[N];
void init(int n=10)
{
	fac[0]=1;
	for(int i=1;i<=n;i++)
		fac[i]=fac[i-1]*i%MOD;
	inv[n]=ksm(fac[n],MOD-2);
	for(int i=n;i>=1;i--)
		inv[i-1]=inv[i]*i%MOD;
	Pw[0]=1;
	for(int i=1;i<=n;i++)
		Pw[i]=Pw[i-1]*2%MOD;
	return;
}
long long C(int n,int m)
{
	if(m>n) return 0;
	else return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}
int r[N],c[N];
char s[N][N];
long long f[N][N][3],g[N][N][3];
int main()
{
	init();
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
		scanf("%s",s[i]);
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			 if(s[i][j]=='.') r[i]|=1<<j,c[j]|=1<<i;
	for(int j=1;j<=m;j++)
		g[n][j][2]=C(m,j)*Pw[m-j]%MOD;
	long long ans=Pw[m];
	for(int i=n;i>=1;i--)
		for(int j=m;j>=1;j--)
		{
			g[i][j][0]=(g[i][j][1]+g[i][j][2])%MOD;
			for(int k=1;k<i;k++)
			{
				int d=i-k;
				f[k][j][1]=(f[k][j][1]+C(i,d)*(g[i][j][2]*2+g[i][j][1])%MOD)%MOD;
				f[k][j][2]=(f[k][j][2]+C(i,d)*(Pw[d]-2)%MOD*g[i][j][2]%MOD)%MOD;
			}
			ans=(ans+g[i][j][2]*(Pw[i]-2)%MOD)%MOD;
			f[i][j][0]=(f[i][j][1]+f[i][j][2])%MOD;
			for(int k=1;k<j;k++)
			{
				int d=j-k;
				g[i][k][1]=(g[i][k][1]+C(j,d)*(f[i][j][2]*2+f[i][j][1])%MOD)%MOD;
				g[i][k][2]=(g[i][k][2]+C(j,d)*(Pw[d]-2)%MOD*f[i][j][2]%MOD)%MOD;
			}
			ans=(ans+f[i][j][2]*(Pw[j]-2)%MOD)%MOD;
		}
	for(int i=1;i<(1<<n);i++)
		for(int j=1;j<(1<<m);j++)
		{
			bool flag=true;
			for(int k=0;k<n;k++)
				if(i&(1<<k))
				{
					int w=r[k]&j;
					if(w==j||w==0)
					{
						flag=false;
						break;
					}
				}
			if(!flag) continue;
			for(int k=0;k<m;k++)
				if(j&(1<<k))
				{
					int w=c[k]&i;
					if(w==i||w==0)
					{
						flag=false;
						break;
					}
				}
			if(!flag) continue;
			int x=__builtin_popcount(i),y=__builtin_popcount(j);
			ans=(ans+(f[x][y][0]+g[x][y][0])%MOD*ksm(C(n,x),MOD-2)%MOD*ksm(C(m,y),MOD-2)%MOD)%MOD;
		}
	printf("%lld",ans);
	return 0;
}

标签:const,int,Keyence,Programming,long,2020,移除,include,MOD
From: https://www.cnblogs.com/zhou-jk/p/17734038.html

相关文章

  • NOMURA Programming Competition 2020
    A-StudyScheduling先算出总时间,然后在减去\(K\)就好了。代码:#include<iostream>#include<cstdio>usingnamespacestd;inth1,m1,h2,m2,k;intmain(){ scanf("%d%d%d%d%d",&h1,&m1,&h2,&m2,&k); intansh=h2-h1,ansm=m2-m1; if......
  • NIKKEI Programming Contest 2019-2
    A-SumofTwoIntegers分奇偶讨论一下就好了,答案为\(\lfloor\frac{n-1}\{2\}\rfloor\)。#include<iostream>#include<cstdio>usingnamespacestd;intn;intmain(){ scanf("%d",&n); printf("%d",(n-1)/2); return0;}B-......
  • Social Infrastructure Information Systems Division, Hitachi Programming Contest
    A-HitachiString满足条件的串即为串长为偶数且相邻两个均为为hi,直接判断即可。代码:#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintN=15;intn;chars[N];intmain(){ scanf("%s",s+1); n=strlen(s+1); if(n&1) ......
  • Yahoo Programming Contest 2019
    A-Anti-Adjacency合法的条件即为\(k\leq\lceil\frac{n}{2}\rceil\)。#include<iostream>#include<cstdio>usingnamespacestd;intn,k;intmain(){ scanf("%d%d",&n,&k); if((n+1)/2>=k)printf("YES"); elsepri......
  • Tokio Marine & Nichido Fire Insurance Programming Contest 2020
    A-Nickname直接输出前三个字符。代码:#include<iostream>#include<cstdio>usingnamespacestd;constintN=25;chars[N];intmain(){ scanf("%s",s+1); printf("%c%c%c",s[1],s[2],s[3]); return0;}B-Tag如果\(v\leqw\),则显然不......
  • DISCO Presents Discovery Channel Code Contest 2020 Qual
    A-DDCCFinals直接模拟即可。#include<iostream>#include<cstdio>usingnamespacestd;intx,y;intmain(){ scanf("%d%d",&x,&y); intans=0; if(x==1)ans+=30; elseif(x==2)ans+=20; elseif(x==3)ans+=10; if(y==1)ans+=30; ......
  • diverta 2019 Programming Contest
    A-ConsecutiveIntegers答案为\(n-k+1\)。#include<iostream>#include<cstdio>usingnamespacestd;intn,k;intmain(){ scanf("%d%d",&n,&k); printf("%d",n-k+1); return0;}B-RGBBoxes枚举\(r,g\),判断一下对应的......
  • soildworks2020双击自动打印问题
    只有通过修改注册表来解决,搜索栏搜索regedit打开注册表编辑器——文件夹HKEY-CLASSES-ROOT——SldAssem.Document——shell1、右键点击shell文件夹新建项,新建项的名称设置未open;2、右键open文件夹新项,名称设置为command;3、继续右键open文件夹新项,名称设置为ddeexec;4、点击open......
  • CAD设计软件下载-CorelCAD 2020官网版 各个版本下载
    CorelCAD2014是Corel公司推出的一款强大CAD制图工具,使用CorelCAD,用户可以轻松创建专业的CAD图形,CorelCAD使用DWG格式作为其主要的图形文件格式,最高支持版本为2014的DWG和DXF文件,提供了与全球范围内大量图形软件和建筑软件的兼容性和交换功能;新版本优化了基于功能区的用户......
  • thinkphp lang命令执行--struts2 代码执行--(QVD-2022-46174)&&(CVE-2020-17530)&&(CV
    thinkphplang命令执行--struts2代码执行--(QVD-2022-46174)&&(CVE-2020-17530)&&(CVE-2021-31805)thinkphplang命令执行(QVD-2022-46174)影响范围6.0.1<=ThinkPHP<=6.0.13ThinkPHP5.0.xThinkPHP5.1.x漏洞复现POC:?+config-create+/&lang=../../../../......