V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sorry
V2EX  ›  程序员

请教个算法问题,给点建议

  •  
  •   sorry · 2014-06-21 21:32:18 +08:00 · 3444 次点击
    这是一个创建于 3807 天前的主题,其中的信息可能已经有所发展或是发生改变。
    每一位上范围是1~30整数,生成13位组合数列

    要求:

    (1)每一位不重复(1,1,....不合格)
    (2)连续位数不大于5(如:1,2,3,4,5,6 ......即不合格);
    (3)相邻两位数差不大于5


    比如:1,2,3,4,6,7,8,9,11,12,13,14,16 即合格

    组合数量特别多,用循环一个个检测速度太慢了,请教大家还有什么建议吗?先谢谢了! ;)
    13 条回复    2014-06-22 11:52:30 +08:00
    ianluo
        1
    ianluo  
       2014-06-21 23:17:16 +08:00   ❤️ 1
    30个数放到数组里然后用rand()%30来取随机坐标,然后碰到相同或者与前一位超过5的话重取,满13个为止,应该满足需求吧。
    lijinma
        2
    lijinma  
       2014-06-21 23:35:00 +08:00   ❤️ 1
    @ianluo 随机取完你再排序? 不排序无法判断连续位数不大于5,划不来;
    ls2110609
        3
    ls2110609  
       2014-06-21 23:56:44 +08:00
    你需要检测还是生成 检测可能可以压缩进一个数据类型内进行
    cassyfar
        4
    cassyfar  
       2014-06-22 00:51:04 +08:00
    题目写得都不清楚。
    生成的数列是sorted还是unsorted的,你是要检测还是要生成啊?如果是检测的话算法最好的也是O(n)了 你指的用循环检测到底是指怎么用循环检测啊?
    casparchen
        5
    casparchen  
       2014-06-22 01:12:11 +08:00 via iPad   ❤️ 1
    这难道不是一个简单dfs么
    casparchen
        6
    casparchen  
       2014-06-22 01:45:11 +08:00
    写了段代码来跑,包含1的就有5908962个。。。
    neoz
        7
    neoz  
       2014-06-22 01:51:48 +08:00   ❤️ 1
    <code>
    #include<iostream>
    #include<random>
    #include<time.h>
    using namespace std;
    int rpc(int x[13],int xx,int ra)
    {
    if(xx>5)
    {
    if((ra-x[xx-1]==1)&&(x[xx-1]-x[xx-2]==1)&&(x[xx-2]-x[xx-3]==1)&&(x[xx-3]-x[xx-4]==1)&&(x[xx-4]-x[xx-5]==1))
    return 1;
    else
    return 0;
    }
    return 0;
    }
    int main()
    {
    clock_t start_time=clock();
    int count=0;
    for(int j=0;j<10000;j++)
    {
    //random_device rd;
    srand( (unsigned)time( NULL ) );
    bool repeat[31]={0};
    int x[13]={0};
    int r=rand()%30+1;
    x[0]=r;
    repeat[r]=1;
    for(int i=1;i<13;i++)
    {
    int ran=rand()%30+1;
    while(repeat[ran]==0)
    {
    ran=rand()%30+1;
    count++;
    }
    if(abs(ran-x[i-1])>5 || rpc(x,i,ran))
    {
    i--;
    }
    else
    {
    x[i]=ran;
    repeat[ran]=1;
    }
    }
    //cout<<j<<"--";
    //for(int i=0;i<13;i++)
    //cout<<x[i]<<" ";
    //cout<<endl;
    }
    clock_t end_time=clock();
    cout<< "Running time is: "<<static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000<<"ms"<<endl;//输出运行时间
    cout<<"The count of ceash is: "<<count<<endl;
    return 0;
    }
    </code>
    测了下是15-25ms之间。用未排序下去做。。。c++初学者。。。不会位运算,第一次想别人的问题,第一次贴出代码。还需努力,见笑了。。。
    casparchen
        8
    casparchen  
       2014-06-22 01:52:32 +08:00   ❤️ 1
    全部有18637773个
    casparchen
        9
    casparchen  
       2014-06-22 01:53:08 +08:00
    casparchen
        10
    casparchen  
       2014-06-22 01:55:24 +08:00
    sorry
        11
    sorry  
    OP
       2014-06-22 07:27:35 +08:00
    @ianluo 这样会遗漏很多。


    @cassyfar 生成的是排过序的


    @casparchen 特别感谢!昨天夜里实现了下,用树做剪枝,动态规划的思想。效率在两分钟内搞定。如果循环的话,组合量是13的30次方,量太大,没法算。。。
    belin520
        12
    belin520  
       2014-06-22 10:06:42 +08:00 via Android
    @casparchen 加script标签
    dingyaguang117
        13
    dingyaguang117  
       2014-06-22 11:52:30 +08:00
    =。= 是啊 就是一个DFS啊
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2773 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 02:39 · PVG 10:39 · LAX 18:39 · JFK 21:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.