CodeForces 388B Fox and Minimal path

做了4天ICM  感觉脑子都坏掉了…  CF落下了2场的题  赶紧追 >.<


题意:

最多用1000个点  画出一幅图  要求满足1节点到2节点的最短路条数为k  输出这幅图的邻接矩阵


思路:

一看k的值10^9  果断开始构造最短路的走法  直觉告诉我们要采用类似BFS的方式(一层一层的加点  这样满足构造出的路径等长)

我首先想的是利用素数去构造  因为素数能构造出合数  可是如果要求最短路条数是一个很大的素数就不好搞(这个思路应该可以继续  我嫌麻烦换了思路  现在想想就是如果遇到大素数情况就异或1  变成最接近的合数递归的做)

由于k最多10位数字  所以我们可以按数字位构造  例如:

k=321  那么我们可以令最短路长度为3  百位、十位、个位分别构造成  3*10*10、2*10*1、1*1*1 

构造方法有了  下面要验证下点够不够用  最费点的就是999999999  但它只需要500-个点  题目给的点太多了

这题要是改成使用的点的个数尽量少就难做了(上面的递归想法可能可以解决)  不过并无此要求


代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

int aim,top;
int bit[11];
vector<int> floor[11];
char maz[1001][1001];

int main()
{
    int i,j,node=3,k,f,s0,s1;
    memset(maz,'N',sizeof(maz));
    scanf("%d",&aim);
    while(aim)
    {
        bit[++top]=aim%10;
        aim/=10;
    }
    for(i=1;i<=top;i++)
    {
        for(j=1;j<=top;j++) floor[j].clear();
        for(j=1;j<i;j++)
        {
            for(k=10;k;k--)
            {
                floor[j].push_back(node);
                node++;
            }
        }
        for(j=1;j<=bit[i];j++)
        {
            floor[i].push_back(node);
            node++;
        }
        for(j=i+1;j<=top;j++)
        {
            floor[j].push_back(node);
            node++;
        }
        for(k=floor[1].size(),j=0;j<k;j++) maz[1][floor[1][j]]=maz[floor[1][j]][1]='Y';
        for(k=floor[top].size(),j=0;j<k;j++) maz[2][floor[top][j]]=maz[floor[top][j]][2]='Y';
        for(f=2;f<=top;f++)
        {
            for(s0=floor[f-1].size(),j=0;j<s0;j++)
            {
                for(s1=floor[f].size(),k=0;k<s1;k++)
                    maz[floor[f-1][j]][floor[f][k]]=maz[floor[f][k]][floor[f-1][j]]='Y';
            }
        }
    }
    printf("%d\n",node-1);
    for(i=1;i<node;i++)
    {
        for(j=1;j<node;j++) printf("%c",maz[i][j]);
        printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值