1 条题解
-
0
解题思路
这个问题可以看作是一个约束满足问题(CSP),我们需要找到一个非负整数矩阵,满足给定的行和列的总和,同时满足所有约束条件。具体步骤如下:
1、输入处理:读取测试用例的数量,然后逐个处理每个测试用例。
2、构建矩阵:根据行和列的总和,尝试填充矩阵的每个元素。
3、约束检查:在填充矩阵时,确保所有给定的约束条件被满足。
4、回溯或线性规划:由于矩阵的大小较小(最多200行20列),可以使用回溯法或线性规划来寻找可行解。
标程
#include <cstdio> #include <cstring> #include <iostream> using namespace std; typedef long long ll; ll n,m,s,ans; int tot; int pn[60],pm[60],ps[60],pri[60]; ll xp[60]; int vis[1000010]; inline void solve(int *cnt,int x) { for(int i=2;i*i<=x;i++) if(x%i==0) { if(!vis[i]) vis[i]=++tot,pri[tot]=i; while(x%i==0) x/=i,cnt[vis[i]]++; } if(x>1) { if(!vis[x]) vis[x]=++tot,pri[tot]=x; cnt[vis[x]]++; } } inline void init() { memset(pn,0,sizeof(pn)),memset(pm,0,sizeof(pm)),memset(ps,0,sizeof(ps)); for(int i=1;i<=tot;i++) vis[pri[i]]=0; } void dfs1(int x,ll now) { if(now>n) return ; if(x>tot) { ans++; return ; } dfs1(x+1,now); for(int i=1;i<=ps[x];i++) dfs1(x+1,now*=pri[x]); } void dfs2(int x,ll now,int flag) { if(now>m) return ; if(x>tot) { ans+=flag*(m/now); return ; } dfs2(x+1,now,flag); if(pn[x]>ps[x]) dfs2(x+1,now*xp[x]*pri[x],-flag); } inline void work() { int t; n=m=s=1,ans=tot=0; scanf("%d",&t),solve(pn,t),n*=t,scanf("%d",&t),solve(pn,t),n*=t,scanf("%d",&t),solve(pn,t),n*=t; scanf("%d",&t),solve(pm,t),m*=t,scanf("%d",&t),solve(pm,t),m*=t,scanf("%d",&t),solve(pm,t),m*=t; scanf("%d",&t),solve(ps,t),s*=t,scanf("%d",&t),solve(ps,t),s*=t,scanf("%d",&t),solve(ps,t),s*=t; solve(ps,2),s<<=1; dfs1(1,1); for(int i=1,j;i<=tot;i++) for(j=xp[i]=1;j<=ps[i];j++) xp[i]*=pri[i]; dfs2(1,1,1); printf("%lld\n",ans); init(); } int main() { // freopen("beacon.in","r",stdin); // freopen("beacon.out","w",stdout); int T; scanf("%d",&T); while(T--) work(); return 0; }
- 1
信息
- ID
- 1397
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者