1 条题解
-
1
非官解(仅供参考)(新手第一次写题解求大佬放过) 数据量 1<=n<=10 非常少了 O(n!) 就能过。 我这里提供一个**O(n^3)**的比较好写和理解的解
#include<bits/stdc++.h> using namespace std; int x[11][11][11],y[11][11][11]; int main(){ int n,b,cntm=10000; //输入与初始化 cin>>n; for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){ cin>>b; x[i][j][b]=1; y[i][j][b]=1; for(int k=1;k<=n;k++)if(!y[k][j][b])y[k][j][b]=2; for(int k=1;k<=n;k++)if(!x[i][k][b])x[i][k][b]=2; } //枚举可能结果并计数 for(int k=1;k<=n;k++){ //按列枚举 for(int i=1;i<=n;i++){ int cnt=0; for(int j=1;j<=n;j++){ if(x[j][i][k]==2)cnt++; else if(x[j][i][k]==0)cnt+=2; } if(cnt<cntm)cntm=cnt; } //按行枚举 for(int i=1;i<=n;i++){ int cnt=0; for(int j=1;j<=n;j++){ if(y[i][j][k]==2)cnt++; else if(y[i][j][k]==0)cnt+=2; } if(cnt<cntm)cntm=cnt; } } cout<<cntm; return 0; }我们如何形成一个解?
3 1 2 1
1 3 4 2
3 2 2 3
4 1 4 4
假如我想要一个第一行全是1的解我们需要将下面的两个1移动上来,一个1直接上移一个1先右移后上移共需要1+2=3步。
我们可以发现一个空位同一列内有1则最少需要1步。同一列没有1则一定最少需要2步。不是空位则最少需要0步。
题目要求要最少的移动次数。我们只需要枚举所有的解并做上述统计取其中最少的即可。如果直接写则是**O(n^4)**比较大而且不好写。
我这里通过x[i][j][k]和y[i][j][k]来存储我们想要的信息并通过初始化来降低时间复杂度
x[1][1][1]==1意思是(1,1)格存在1
x[1][1][1]==2意思是(1,1)格没一但所在行存在1
x[1][1][1]==0则是(1,1)格上面两种都不满足
y[i][j][k]同理只不过==2时是所在列
这样就可以同过直接遍历x,y数组来获取我们所有解的移动次数
信息
- ID
- 1476
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 4
- 已通过
- 2
- 上传者