POJ 3074 Sudoku (Dancing Links)

传送门:http://poj.org/problem?id=3074


DLX 数独的9*9的模板题。

具体建模详见下面这篇论文。其中9*9的数独怎么转化到精确覆盖问题,以及相关矩阵行列的定义都在下文中,描述的十分清晰

http://wenku.baidu.com/view/4ab7bd00a6c30c2259019eae.html

有关Dancing Links的英文论文详见下面链接

http://wenku.baidu.com/view/60eb28ded15abe23482f4d77.html

中文的:

http://wenku.baidu.com/view/d8f13dc45fbfc77da269b126.html



AC代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<algorithm>

using namespace std;
//   列:(行+列+块)*9种可能+9*9个格子
//   行: 9*9*9  表示第i行第j列填k
const int MAXN=(9+9+9)*9+9*9+9*9*9*9*9*4+10;
#define INF 0xFFFFFF
int size;
int head,sz;
int U[MAXN],D[MAXN],L[MAXN],R[MAXN];
int H[MAXN],ROW[MAXN],C[MAXN],S[MAXN],O[MAXN];

void remove(int c)
{
    L[R[c]]=L[c];
    R[L[c]]=R[c];
    for(int i=D[c];i!=c;i=D[i])
    {
        for(int j=R[i];j!=i;j=R[j])
        {
            U[D[j]]=U[j];
            D[U[j]]=D[j];
            --S[C[j]];
        }
     }
}

void resume(int c)
{
    for(int i=U[c];i!=c;i=U[i])
    {
        for(int j=L[i];j!=i;j=L[j])
        {
            ++S[C[j]];
            U[D[j]]=j;
            D[U[j]]=j;
          }
     }
     L[R[c]]=c;
     R[L[c]]=c;
}

bool dfs(int k)
{
    if(R[head]==head)
    {
        sort(O,O+9*9);
        int p=0;
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {
                int num=O[p++];
                //cout<<num<<endl;
                num=num-(i*9+j)*9;
                printf("%d",num);
            }
        }
        printf("\n");
        return  true;
    }
    int s=INF,c;
    for (int t=R[head];t!=head;t=R[t])
    {
        if (S[t]<s)
        {
            s=S[t];
            c=t;
        }
     }
     remove(c);
     for(int i=D[c];i!=c;i=D[i])
     {
          O[k]=ROW[i];
          for(int j=R[i];j!=i;j=R[j])
              remove(C[j]);
          if(dfs(k+1))
               return  true;
          for(int j=L[i];j!=i;j=L[j])
               resume(C[j]);
     }
     resume(c);
     return  false;
}

void initDL(int n)
{
    head=0;
    for(int i=0;i<=n;i++)
    {
        U[i]=i;D[i]=i;
        L[i]=i-1;R[i]=i+1;
        S[i]=0;
    }
    R[n]=0;L[0]=n;S[0]=INF+1;
    sz=n+1;
    memset(H,0,sizeof(H));
}

void insert(int i, int j)
{
    if(H[i])
    {
        L[sz]=L[H[i]];
        R[sz]=H[i];
        L[R[sz]]=sz;
        R[L[sz]]=sz;
    }
    else
    {
        L[sz]=sz;
        R[sz]=sz;
        H[i]=sz;
    }
    U[sz]=U[j];
    D[sz]=j;
    U[D[sz]]=sz;
    D[U[sz]]=sz;
    C[sz]=j;
    ROW[sz]=i;
    ++S[j];
    ++sz;
}

char str[200];

void build()
{
    int p=0;
    initDL(9*9*4);
    for(int i=0;i<9;i++)
        for(int j=1;j<=9;j++,p++)
        {
            int base=(i*9+j-1)*9;
            if(str[p]=='.')
            {
                for(int k=1;k<=9;k++)
                {
                    int r;
                    r=base+k;
                    //第i行有数字k
                    insert(r,i*9+k);
                    //第j列有数字k
                    insert(r,9*9+(j-1)*9+k);
                    //第k块有数字k
                    int block=(j-1)/3*3+i/3;
                    insert(r,9*9*2+block*9+k);
                    //第i行j列有一个数字(限制一个格子只填一个数)
                    insert(r,9*9*3+i*9+j);
                }
            }
            else
            {
                int k=str[p]-'0';
                int r=base+k;
                //第i行有数字k
                insert(r,i*9+k);
                //第j列有数字k
                insert(r,9*9+(j-1)*9+k);
                //第k块有数字k
                int block=(j-1)/3*3+i/3;
                insert(r,9*9*2+block*9+k);
                //第i行j列有一个数字(限制一个格子只填一个数)
                insert(r,9*9*3+i*9+j);
            }
        }
}

int main()
{
    size=9; //9*9数独
    while(~scanf("%s",str))
    {
        if(strcmp(str,"end")==0)
            break;
        build();
        dfs(0);
    }
    return 0;
}


1. 用户与身体信息管理模块 用户信息管理: 注册登录:支持手机号 / 邮箱注册,密码加密存储,提供第三方快捷登录(模拟) 个人资料:记录基本信息(姓名、年龄、性别、身高、体重、职业) 健康目标:用户设置目标(如 “减重 5kg”“增肌”“维持健康”)及期望周期 身体状态跟踪: 体重记录:定期录入体重数据,生成体重变化曲线(折线图) 身体指标:记录 BMI(自动计算)、体脂率(可选)、基础代谢率(根据身高体重估算) 健康状况:用户可填写特殊情况(如糖尿病、过敏食物、素食偏好),系统据此调整推荐 2. 膳食记录与食物数据库模块 食物数据库: 基础信息:包含常见食物(如米饭、鸡蛋、牛肉)的名称、类别(主食 / 肉类 / 蔬菜等)、每份重量 营养成分:记录每 100g 食物的热量(kcal)、蛋白质、脂肪、碳水化合物、维生素、矿物质含量 数据库维护:管理员可添加新食物、更新营养数据,支持按名称 / 类别检索 膳食记录功能: 快速记录:用户选择食物、输入食用量(克 / 份),系统自动计算摄入的营养成分 餐次分类:按早餐 / 午餐 / 晚餐 / 加餐分类记录,支持上传餐食照片(可选) 批量操作:提供常见套餐模板(如 “三明治 + 牛奶”),一键添加到记录 历史记录:按日期查看过往膳食记录,支持编辑 / 删除错误记录 3. 营养分析模块 每日营养摄入分析: 核心指标计算:统计当日摄入的总热量、蛋白质 / 脂肪 / 碳水化合物占比(按每日推荐量对比) 微量营养素分析:检查维生素(如维生素 C、钙、铁)的摄入是否达标 平衡评估:生成 “营养平衡度” 评分(0-100 分),指出摄入过剩或不足的营养素 趋势分析: 周 / 月营养趋势:用折线图展示近 7 天 / 30 天的热量、三大营养素摄入变化 对比分析:将实际摄入与推荐量对比(如 “蛋白质摄入仅达到推荐量的 70%”) 目标达成率:针对健
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值