ural 1667 Square Country 3,构造

来源:互联网 发布:卡拉ok播放器mac 编辑:程序博客网 时间:2024/06/05 07:43
今天学习了一个巧妙的构造题目:ural 1667 Square Country 3
要求构造一个矩阵满足元素不重复而且每个元素、每行的和、每列的和都是完全平方数。

做法是随机构造第一行b[1..m]和第一列a[1..n],然后矩阵c[i][j]=a[i]*b[j],这样是满足条件的。

不过为什么随机构造能够很快出解我还不会证明,希望有爱的同学补上。。


#include<cstdio>#include<cstring>#include<cstdlib>#include<ctime>#include<cmath>#include<set>using namespace std;#define NN 30const int K=300;int cas,tcas;int a[NN],b[NN],n,m;long long c[NN][NN];int sq[K+100];int us[K+100];int sv[NN];void pre(){    int i;    for(i=1;i<=K+10;++i){        sq[i]=i*i;    }}int issqr(int n){    int tmp=sqrt(n);    if (tmp*tmp==n||(tmp+1)*(tmp+1)==n) return 1;    return 0;}void gao(int a[],int n){    int i,tmp,sum,flag=0;    while(1){        sum=0;        for(i=1;i<n;++i){            while(1) {tmp=rand()%K+10;if (!us[tmp]) break;}            a[i]=sq[tmp];            sv[i]=tmp;            us[tmp]=1;            sum+=a[i];        }        for(i=1;i<=K;++i)if (!us[i]){            if (issqr(sum+sq[i])){                us[i]=1;a[n]=sq[i];                flag=1;break;            }        }        if (flag==1) break;        for(i=1;i<n;++i){            us[sv[i]]=0;        }    }}set<long long> st;int check(int n,int m){    int i,j;    st.clear();    for(i=1;i<=n;++i){        for(j=1;j<=m;++j){            if (st.find(c[i][j])!=st.end()) return 0;            st.insert(c[i][j]);        }    }    return 1;}int main(){    //freopen("1667in.txt","r",stdin);    int i,j;    pre();    srand(time(NULL));    scanf("%d",&tcas);    for(cas=1;cas<=tcas;++cas){        scanf("%d%d",&n,&m);        while(1){            memset(us,0,sizeof(us));            gao(a,n);            //for(i=1;i<=n;++i){printf("%d ",a[i]);}puts("111");            gao(b,m);            //for(i=1;i<=m;++i){printf("%d ",b[i]);}puts("");            for(i=1;i<=n;++i){                for(j=1;j<=m;++j){                    c[i][j]=(long long)a[i]*b[j];                }            }            if (check(n,m)) break;        }        //while(1);        //printf("   cas=%d\n",cas);        for(i=1;i<=n;++i){            for(j=1;j<=m;++j){                printf("%I64d",c[i][j]);                if (j!=m) printf(" ");                else printf("\n");            }        }        if (cas!=tcas) printf("\n");    }    return 0;}


原创粉丝点击