编程之美2014格格取数

来源:互联网 发布:淘宝价格怎么设置 编辑:程序博客网 时间:2024/04/28 18:41
#include<iostream>typedef struct{    int x,y,key,p;} Max;void QuickSortRowP(Max R[100][100],int x,int s, int t){    int i=s, j=t;    Max tmp, tra;    if(s<t)    {        tmp=R[x][s];        while(i!=j)        {            while(j>i&&R[x][j].p>=tmp.p)            {                j--;            }            tra=R[x][i];            R[x][i]=R[x][j];            R[x][j]=tra;            while(i<j&&R[x][i].p<tmp.p)            {                i++;            }            tra=R[x][j];            R[x][j]=R[x][i];            R[x][i]=tra;        }        R[x][i]=tmp;        QuickSortRowP(R,x,s,i-1);        QuickSortRowP(R,x,i+1,t);    }}void QuickSortCol(Max R[100][100],int y,int s, int t){    int i=s, j=t;    Max tmp, tra;    if(s<t)    {        tmp=R[s][y];        while(i!=j)        {            while(j>i&&R[j][y].key>=tmp.key)            {                j--;            }            tra=R[i][y];            R[i][y]=R[j][y];            R[j][y]=tra;            while(i<j&&R[i][y].key<tmp.key)            {                i++;            }            tra=R[j][y];            R[j][y]=R[i][y];            R[i][y]=tra;        }        R[i][y]=tmp;        QuickSortCol(R,y,s,i-1);        QuickSortCol(R,y,i+1,t);    }}int main(){    int T,m,n,t,i,j,ii,jj,coun,LACK,NEWLACK,flag,sum[100],OPER[100],RF[100][100];    Max conum[100][100],CHOOSE[100],TEMP;    std::cin>>T;    for(t=0; t<T; ++t)    {        std::cin>>m>>n;        for(i=0; i<m; ++i) //input        {            for(j=0; j<n; ++j)            {                std::cin>>conum[i][j].key;                conum[i][j].p=0;                conum[i][j].x=i;                conum[i][j].y=j;            }        }        if(m>n)        {            for(j=0; j<n; ++j) //reverse            {                for(i=j+1; i<m; ++i)                {                    conum[j][i].p=0;                    ii=conum[j][i].y;                    conum[j][i].y=conum[i][j].x;                    conum[i][j].x=ii;                    ii=conum[j][i].x;                    conum[j][i].x=conum[i][j].y;                    conum[i][j].y=ii;                    ii=conum[j][i].key;                    conum[j][i].key=conum[i][j].key;                    conum[i][j].key=ii;                }            }            i=m;            m=n;            n=i;        }        for(j=0; j<n; ++j)//col sort <- key step        {            QuickSortCol(conum,j,0,m-1);        }        for(j=0; j<n; ++j)//p increase initialize        {            for(i=0; i<m; ++i)            {                conum[i][j].p=conum[i][j].key-conum[0][j].key;            }        }        for(j=0; j<n; ++j)//CHOOSE and OPER initialize        {            CHOOSE[j]=conum[0][j];            OPER[j]=0;        }        coun=0;        for(j=0; j<n; ++j) //LACK initialize        {            for(i=0; i<m; ++i)            {                if(CHOOSE[j].x==i)                {                    OPER[i]+=1;                }            }        }        for(i=0; i<m; ++i)        {            if(OPER[i])            {                coun+=1;                OPER[i]=0;            }        }        LACK=m-coun;        coun=0;        for(i=0; i<m; ++i)        {            QuickSortRowP(conum,i,0,n-1);        }        for(i=0; i<m; ++i)//RF initialize        {            for(j=0; j<n; ++j)            {                RF[i][j]=1;            }        }        for(j=0; j<n; ++j)        {            RF[0][j]=0;        }        while(LACK)        {            for(j=0; j<n; ++j)            {                for(i=0; i<m; ++i)                {                    if(RF[i][j]==1)                    {                        TEMP=CHOOSE[conum[i][j].y];//TEMP initialize                        CHOOSE[conum[i][j].y]=conum[i][j];                        flag=conum[i][j].y;//flag initialize                        //compute new lack                        for(jj=0; jj<n; ++jj)                        {                            for(ii=0; ii<m; ++ii)                            {                                if(CHOOSE[jj].x==ii)                                {                                    OPER[ii]+=1;                                }                            }                        }                        for(ii=0; ii<m; ++ii)                        {                            if(OPER[ii])                            {                                coun+=1;                                OPER[ii]=0;                            }                        }                        NEWLACK=m-coun;//NEWLACK initialize                        coun=0;                        //                        if(NEWLACK<LACK)                        {                            LACK=NEWLACK;                            RF[i][j]=0;                            continue;                        }                        else                        {                            CHOOSE[flag]=TEMP;                        }                    }                }            }        }        sum[t]=0;//sum initialize        for(j=0; j<n; ++j)        {            sum[t]+=CHOOSE[j].key;        }    }//T!! do not delete    for(t=0; t<T; ++t)    {        std::cout<<"Case "<<t+1<<": "<<sum[t]<<std::endl;    }}//main!! do not delete


矩阵采用结构体,记录所在的x轴、y轴位置,key值和一个辅助变量p,p记录垂直排序后每一列的递增情况。


 变量说明:


 T,m,n//循环次数,行,列   ,t,i,j,ii,jj// 计数    coun,LACK,NEWLACK,OPER[100]//用于计算未覆盖的行数     flag//标记     RF[100][100]//辅助矩阵     sum[100]//记录结果 conum[100][100]//结构矩阵      CHOOSE[100]//选出的元素 


没有刻意遵循某种算法,总体上是按照排序优先的原则进行遍历,个人认为行和列中较大的值代表必须选出的元素的总数。


 大致思想是先考虑每一列再考虑每一行。首先使列数n恒大于等于行数m(不满足则转置),对每一列垂直排序,最上方一行即为每一列最小值的组合并作为CHOOSE[]的初始值。如果CHOOSE[]没有覆盖每一行,对除第一行外,对列的递增情况进行水平排序;计算未覆盖行数LACK,判断是否覆盖了每一行,如果没有覆盖全部行则循环更新CHOOSE[]和LACK直到完全覆盖每一行为止。


自己测试多组数据都是对的,不知道为什么WA,就当写着玩儿了~

0 0
原创粉丝点击