这题有点年份了,大一校赛的网络赛题目,当年a了5题后直接放掉了这题,使得这题一直是我该oj上唯一的一抹红,现在再看来,早已变成了水题一道,稍稍谢谢,一发轻松ac,甚是欣慰
1143 方格填数
思路:由于枚举所有结果,只有362880中情况,加上100组数据,完全可以dfs枚举,注意避免重复访问剪枝一下就好了,然后预处理一下gcd的值,ok
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
/*
typedef struct FG
{
int k;
int t;
vector <int> p;
bool in;
}Fg;
typedef struct PX
{
int id;
int k;
}Px;
Fg a[9];
Px b[9];
*
int gcd(int a,int b)
{
int t;
while(b)
{
t = a%b;
a = b;
b = t;
}
return a;
}
int cmp(const Px &a,const Px &b)
{
return a.k>b.k;
}
int cmpint(const int &a,const int &b)
{
return a>b;
}
int main()
{
while(scanf("%d%d%d%d%d%d%d%d%d",&a[0].k,&a[1].k,&a[2].k,&a[3].k,&a[4].k,&a[5].k,&a[6].k,&a[7].k,&a[8].k)!=EOF)
{
for(int i=0;i<9;i++)
{
int temp=0;
b[i].id=i;
b[i].k=a[i].k;
a[i].p.clear();
for(int j=0;j<9;j++)
{
if(gcd(a[j].k,a[i].k)==1)
{
temp++;
a[i].p.push_back(j);
}
}
a[i].t=temp;
}
sort(b,b+9,cmp);
if(b[0].k<4||b[4].k<3||b[8].k<2)
{
printf("%d\n",0);
}
else
{
int sum=0;
for(int i=0;b[i].k>=4;i++)
{
for(int j=0;j<9;j++)
{
a[j].in=false;
}
a[b[i].id].in=true;
vector <int> ::iterator it1,it2,it3,it4;
sort(a[b[i].id].p.begin(),a[b[i].id].p.end(),cmpint);
for(it1=a[b[i].id].p.begin();it1!=a[b[i].id].p.end()&&a[*it1].k>=3;it1++)
{
a[*it1].in=true;
for(it2=it1+1;it2!=a[b[i].id].p.end()&&a[*it2].k>=3;it2++)
{
a[*it2].in=true;
for(it3=it2+1;it3!=a[b[i].id].p.end()&&a[*it3].k>=3;it3++)
{
a[*it3].in=true;
for(it4=it3+1;it4!=a[b[i].id].p.end()&&a[*it4].k>=3;it4++)
{
a[*it4].in=true;
a[*it4].in=false;
}
a[*it3].in=false;
}
a[*it2].in=false;
}
a[*it1].in=false;
}
}
}
for(int i=0;i<9;i++)
{
cout<<a[i].id<<" "<<a[i].k<<endl;
}
}
return 0;
}
int a[9];
int m[3][3];
bool a_in[9];
bool m_in[3][3];
int b[2][2]={{0,1},{1,0}};
int m[9];
int cmp(const int &a,const int &b)
{
return a>b;
}
int dfs(int x,int y,int sum)
{
if(x<0||x>2||y<0||y>2)
return sum;
for(int i=0;i<9;i++)
{
cout<<"x="<<x<<"y="<<y<<"sum="<<sum<<endl;
if(a_in[i])
continue;
if(!m_in[x][y])
{
if(x>0&&m_in[x-1][y]&&gcd(m[x-1][y],a[i])!=1)
continue ;
if(x<2&&m_in[x+1][y]&&gcd(m[x+1][y],a[i])!=1)
continue ;
if(y>0&&m_in[x][y-1]&&gcd(m[x][y-1],a[i])!=1)
continue ;
if(y<2&&m_in[x][y+1]&&gcd(m[x][y+1],a[i])!=1)
continue ;
m_in[x][y]=true;
m[x][y]=a[i];
a_in[i]=true;
dfs(x+b[0][0],y+b[0][1],sum);
dfs(x+b[1][0],y+b[1][1],sum);
m_in[x][y]=false;
a_in[i]=false;
}
}
if(x==2&&y==0)
return sum+1;
else
return sum;
}
bool can(int x,int k)
{
if(x==0)
return true;
else if(x%3>0&&gcd(k,m[x-1])!=1)
return false;
else if(x>2&&gcd(k,m[x-3])!=1)
return false;
else
return true;
}
int dfs(int x,int sum)
{
if(x==9)
{
sum++;
return sum;
}
for(int i=0;i<9;i++)
{
if(a_in[i])
continue;
else
{
if(can(x,a[i]))
{
m[x]=a[i];
a_in[i]=true;
cout<<"x="<<x<<"i="<<i<<"sum="<<sum<<endl;
sum=dfs(x+1,sum);
a_in[i]=false;
}
}
}
return sum;
}
int main()
{
while(scanf("%d%d%d%d%d%d%d%d%d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8])!=EOF)
{
sort(a,a+9,cmp);
if(a[0]<4||a[4]<3||a[8]<2)
{
printf("%d\n",0);
}
else
{
memset(a_in,false,9*sizeof(bool));
memset(m_in,false,9*sizeof(bool));
int sum=0;
sum=dfs(0,0,sum);
sum=dfs(0,sum);
printf("%d\n",sum);
}
}
return 0;
}
*/
int a[10];
bool near[10][10];
int gcd(int a,int b)
{
return b == 0 ? a : gcd(b, a % b);
}
int sum;
int pos[10];
vector <int> ne[10];
bool in[10];
void dfs(int k)
{
if(k==9)
{
sum++;
}
else
{
for(int i=0;i<9;i++)
{
if(in[i])
{
continue;
}
int len = ne[k].size();
int j;
for(j=0;j<len;j++)
{
if(!near[i][pos[ne[k][j]]])
{
break;
}
}
if(j<len)
{
continue;
}
pos[k] = i;
in[i] = true;
dfs(k+1);
in[i] = false;
}
}
return ;
}
int main()
{
ne[0].clear();
ne[1].clear();
ne[1].push_back(0);
ne[2].clear();
ne[2].push_back(1);
ne[3].clear();
ne[3].push_back(0);
ne[4].clear();
ne[4].push_back(3);
ne[4].push_back(1);
ne[5].clear();
ne[5].push_back(4);
ne[5].push_back(2);
ne[6].clear();
ne[6].push_back(3);
ne[7].clear();
ne[7].push_back(6);
ne[7].push_back(4);
ne[8].clear();
ne[8].push_back(7);
ne[8].push_back(5);
while(scanf("%d",&a[0])!=EOF)
{
memset(near,false,sizeof(near));
memset(in,false,sizeof(in));
sum = 0;
for(int i=1;i<9;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(gcd(a[i],a[j])==1)
{
near[i][j] = true;
}
}
}
dfs(0);
printf("%d\n",sum);
}
}
看着大一自己写的长长的代码,各种结构体,排序,比较,已经早已看不懂当时的思路了,当然也没什么闲工夫再去琢磨,能发现gcd和dfs,总思路算是没错的吧,满满的回忆,就把代码都贴在开头了,作为永恒的纪念