• pku 1020


    题意:就是用几个小正方形,去拼成个大的正方形。

    思路:从大到小,从左到右,深搜,不是很难,

    网上的代码很简洁,我就不用自己的了,加点注释吧

    #include <stdio.h>
    #include <memory.h>
    int cnt[20]; //记录长度为i的正方形个数
    int len[50]; //记录目前第i列覆盖长度
    int cake_side, npiece;
    bool chk(int used)
    {
    if(used == npiece) //所有正方形都用上了,返回真,跳出
    return true;
    int min = 100, ind = -1;
    for(int i = 0; i < cake_side; i++) //枚举大蛋糕边的长度
    if(min > len[i])
    {
    min = len[i]; /* 找目前覆盖最小的那一列 */
    ind = i; //标记标号
    }
    //先放大的后放小的
    for(int i = 1; i <= 10; i++)
    if(cnt[i] && len[ind] + i <= cake_side) //有i这个边长,加上刚才最小的覆盖,合起来的值小于等于大正方形的边长
    {
    int wid = 0;/* 放置宽为 i 的 */
    for(int j = ind; j < cake_side; j++) //检测宽度是否符合要求,即是否放得下边长为i的正方形
    if(len[j] == len[ind]) wid++;
    else break;
    if(wid >= i) //能放下
    {
    cnt[i]--; //在下一层递归中,i用掉了一个
    for(int j = ind; j < ind + i; j++) //从ind到i+ind列覆盖的值更新,进入下一层递归
    len[j] += i;
    if(chk(used + 1)) //used表示用的正方形数
    return true;
    for(int j = ind; j < ind + i; j++) //更新值变回来,继续循环,不影响下次枚举
    len[j] -= i;
    cnt[i]++; //同上
    }
    }
    return false;
    }
    int main()
    {
    int cs = 0;
    scanf("%d", &cs);
    while(cs--)
    {
    memset(len, 0, sizeof(len));
    memset(cnt, 0, sizeof(cnt));
    int area = 0;
    scanf("%d %d", &cake_side, &npiece);
    for(int i = 0; i < npiece; i++)
    {
    int side;
    scanf("%d", &side);
    cnt[side]++;
    area += side * side;
    }
    if(cake_side * cake_side == area && chk(0))
    printf("KHOOOOB!\n");
    else
    printf("HUTUTU!\n");
    }
    return 0;
    }
  • 相关阅读:
    堆的创建、优先队列、topk、堆排序C语言实现
    HTTPS加密原理
    go shard map实现
    Python进程间通信
    TCP 半连接队列和全连接队列
    WireShark过滤语法
    TCP拥塞机制
    【企业管理实务系列】低值易耗品管理办法
    CV之Face Change:基于人工智能实现国内众多一线美女明星换脸(基于Face++输出4*106个特征点定位+融合代码、deepfake技术)
    【转发】农行银企直联XML对接socket SAP EPIC
  • 原文地址:https://www.cnblogs.com/FreeAquar/p/2155215.html
Copyright © 2020-2023  润新知