首页 > 其他分享 >Gym100825C-KenKen-You-Do-It题解

Gym100825C-KenKen-You-Do-It题解

时间:2023-03-01 15:46:51浏览次数:57  
标签:Do 顺序 15 数字 int 题解 KenKen 摆放 集合

题目传送门

题意:在一个矩阵上选中了若干个格子,保证连通。你需要在这些格子中填数,使得:每行每列不能重复,且这些数进行给定运算(可以认为只有加法和乘法)的结果为给定的数值。求填数的方案数。

首先考虑朴素的搜索。将选中的格子按行列排序(顺序剪枝),依次考虑每个格子填的数,中途维护每行每列的数字使用情况(可以状压),进行可行性剪枝。这个做法虽然可以通过本题,但跑得非常慢且需要卡常。

考虑进一步优化。我们发现,“运算结果固定”这条限制与数字摆放顺序无关,而只与使用的数字集合有关;“每行每列不重复”这条限制只与数字摆放顺序和位置之间是否相同有关,而与具体数字无关。于是这两部分可以分开考虑。

假设只考虑后一条限制,我们预处理出对于每一种“数字区分集合”(即有多少个不同的元素,每个不同的元素各用了多少次,而不关心到底是多少)的摆放方案数。这个可以使用搜索来计算:搜索每个位置,维护当前用了几个数字以及第几个数字用的次数,每次考虑这个位置放以前的哪个数字或新开一个数字使用。对于“数字区分集合”可以使用“每个数字用的次数”的 vector 排序后来表示(相同的 vector 意味着相同的“区分集合”)。可以使用 map<vector<int>,int> 来记录。

然后考虑第一条限制。此时与摆放顺序无关,考虑使用哪些数字集合。这个也可以使用搜索,由于此时没有顺序限制,可以强制从小到大填数(大幅减少状态数)。当确定了一个数字集合时,使用预处理出来的“该摆放集合的方案数”可快速得到答案。注意对于出现次数相同的两个数,可以任意交换顺序,所以答案需要对每个出现次数相同的数的个数求阶乘,相乘得到最终答案。

By cxm1024 From RNS3

#include<bits/stdc++.h>
using namespace std;
int n,m,t,jc[11],ans=0;
char ch;
int x[15],y[15];
map<vector<int>,int> mp;
int cnt[15],xvis[15],yvis[15];
void init(int now,int tot) {
	if(now==0) {
		vector<int> v;
		for(int i=1;i<=tot;i++)
			v.push_back(cnt[i]);
		sort(v.begin(),v.end());
		mp[v]++;
		return;
	}
	for(int i=1;i<=tot+1;i++) {
		if(xvis[x[now]]&(1<<i)) continue;
		if(yvis[y[now]]&(1<<i)) continue;
		cnt[i]++;
		xvis[x[now]]^=(1<<i),yvis[y[now]]^=(1<<i);
		init(now-1,max(tot,i));
		cnt[i]--;
		xvis[x[now]]^=(1<<i),yvis[y[now]]^=(1<<i);
	}
}
void dfs1(int now,int sum,int bd) {
	if(now==0) {
		if(sum!=0) return;
		vector<int> v;
		for(int i=1;i<=n;i++)
			if(cnt[i]) v.push_back(cnt[i]);
		sort(v.begin(),v.end());
		int res=mp[v],lst=0;
		for(int i=1;i<v.size();i++)
			if(v[i]!=v[i-1]) res*=jc[i-lst],lst=i;
		res*=jc[v.size()-lst];
		ans+=res;
		return;
	}
	if(sum>now*n||sum<now) return;
	for(int i=bd;i<=n;i++) {
		cnt[i]++;
		dfs1(now-1,sum-i,i);
		cnt[i]--;
	}
}
void dfs2(int now,int sum,int bd) {
	if(now==0) {
		if(sum!=1) return;
		vector<int> v;
		for(int i=1;i<=n;i++)
			if(cnt[i]) v.push_back(cnt[i]);
		sort(v.begin(),v.end());
		int res=mp[v],lst=0;
		for(int i=1;i<v.size();i++)
			if(v[i]!=v[i-1]) res*=jc[i-lst],lst=i;
		res*=jc[v.size()-lst];
		ans+=res;
		return;
	}
	for(int i=bd;i<=n;i++) {
		if(sum%i!=0) continue;
		cnt[i]++;
		dfs2(now-1,sum/i,i);
		cnt[i]--;
	}
}
signed main() {
	jc[0]=1;
	for(int i=1;i<=10;i++)
		jc[i]=jc[i-1]*i;
	cin>>n>>m>>t>>ch;
	for(int i=1;i<=m;i++)
		cin>>x[i]>>y[i];
	if(ch=='-') {
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(i!=j&&(i-j==t||j-i==t))
					ans++;
		cout<<ans<<endl;
		return 0;
	}
	if(ch=='/') {
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(i!=j&&(j*t==i||i*t==j))
					ans++;
		cout<<ans<<endl;
		return 0;
	}
	init(m,0);
	if(ch=='+') dfs1(m,t,1);
	else dfs2(m,t,1);
	cout<<ans<<endl;
	return 0;
}

标签:Do,顺序,15,数字,int,题解,KenKen,摆放,集合
From: https://www.cnblogs.com/cxm1024/p/17168449.html

相关文章

  • Gym100959I-Robots题解
    题意:平面直角坐标系上有\(n\)个机器人,每个机器人有一个上下左右之一的方向,初始所有机器人静止。在第\(0\)秒,你让第一个机器人开始朝它的方向移动,速度为每秒一个单位。......
  • Gym101252B-Kakuro题解
    题目传送门题意:有一个矩阵,每个格子为黑色或白色。你需要向白色格子中填\(1\sim9\)的整整睡。从某一个黑色格子的右侧往右连续的一段极长的白色格子被称为一个run,往下......
  • docker无法启动
    报错日志:FailedtochownsocketatstepGROUP:NosuchprocessFailedtolistenonDockerSocketfortheAPI.Subject:Unitdocker.sockethasfailed 解决方案......
  • 基于 Docker Compose 安装 ElasticView
    1、Docker安装参考:https://www.cnblogs.com/a120608yby/p/9883175.html2、DockerCompose安装参考:https://www.cnblogs.com/a120608yby/p/14582853.html3、服务......
  • DockQuery 天狼 v1.2.0 正式发布
    DockQuery天狼经过2022年的孵化,于2022年年底发布了第一个版本。在春回大地万象更新之际,DockQuery发布了1.2.0版本,也是我们公开招募第一批产品体验官的版本。在这个......
  • C#、IIS获取时间带星期或日期问题解决
    ,获取时间老是带星期,如:2018-8-8星期日12:00:00,造成写入数据库时无法识别为时间格式报错。试了修改区域语言和修改指定注册表均无效。   解决方法一:在代码里处理时......
  • Docker生成镜像
    Docker生成镜像 dockercommit:提交为新镜像:dockercommit-m="描述消息"-a="作者"容器ID或容器名镜像名:TAG#例:#dockercommit-m="修改了首页"-a="华......
  • SkeyeVSS综合安防视频云服务WEB H5无插件播放RTSP摄像机解决方案,拒绝插件,拥抱H5,Window
    SkeyeVSS综合安防视频云服务WEBH5无插件播放RTSP摄像机解决方案,拒绝插件,拥抱H5,WindowsPC、Liunx、Android、iOS全平台支持市场需求视频流媒体监控行业已经进入了互联网......
  • 完美解决 Windows 10 无操作或锁屏时两分钟自动睡眠问题
    参考 https://www.ioiox.com/archives/113.html 开启隐藏选项无人参与系统睡眠超时  无人参与系统睡眠超时是指当系统正常使用未被锁定(Win+L)时,在无操作的情况......
  • 虹科分享 | Domo零售行业商业智能白皮书:《从零售企业的数据中获取价值》
    推荐语:Domo零售行业商业智能白皮书—《从零售企业的数据中获取价值》总结了传统零售业在数字化转型过程中面临的挑战,并基于虹科DomoBI工具从数字体验、库存管理、销售业绩......