zoukankan      html  css  js  c++  java
  • MemSQL start[c]up Round 1.E

    完全的乱搞题啊。。。 被坑的要死。

    拿到题目就觉得是规律题加构造题, 然后找了了几个小时无果,只知道n为奇数的时候是一定无解的,然后当n为偶数的时候可能有很多解,但是如果乱选择的话,很有可能形成无解的情况。

    然后想到了类似于估价函数之类的东西, 一开始我就想到了让几个关键的点设价值设成很大,然后在构造解的时候尽量不选这些点,然后。。。 发现数据到30左右就出错了。  然后再进一步的想,把每个点都估计一个价值,价值的大小为到0的距离。 然后就可以保证在构造解的时候尽量选离0远的点,这样一直选,一直选,一直选。。。就不可思议的过了。。。 

    不知道具体证明,但是思想感觉没有错误。因为这题无解的情况就是过早的选到了0. 如果每次都尽量选离0远的点,局部最优可以成为整体最优。

    E. The Red Button
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Piegirl found the red button. You have one last chance to change the inevitable end.

    The circuit under the button consists of n nodes, numbered from 0 to n - 1. In order to deactivate the button, the n nodes must be disarmed in a particular order. Node 0 must be disarmed first. After disarming node i, the next node to be disarmed must be either node(2·i) modulo n or node (2·i) + 1 modulo n. The last node to be disarmed must be node 0. Node 0 must be disarmed twice, but all other nodes must be disarmed exactly once.

    Your task is to find any such order and print it. If there is no such order, print -1.

    Input

    Input consists of a single integer n (2 ≤ n ≤ 105).

    Output

    Print an order in which you can to disarm all nodes. If it is impossible, print -1 instead. If there are multiple orders, print any one of them.

    Sample test(s)
    input
    2
    output
    0 1 0
    input
    3
    output
    -1
    input
    4
    output
    0 1 3 2 0
    input
    16
    output
    0 1 2 4 9 3 6 13 10 5 11 7 15 14 12 8 0


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <map>
    #include <queue>
    #include <sstream>
    #include <iostream>
    using namespace std;
    #define INF 0x3fffffff
    #define N 100100
    
    struct node
    {
        int to,next;
    }edge[2*N];
    
    
    
    void check()
    {
        int n=18;
        for(int i=0;i<n;i++)
        {
            int a=i*2;
            a=a%n;
            int b=i*2+1;
            b=b%n;
            printf("%d: ",i);
            if(a!=i)
                printf("%d ",a);
            if(b!=i)
                printf("%d
    ",b);
        }
    }
    
    int mark[N];
    int g[N][2];
    int a[N];
    int save[N];
    queue<int > que[2];
    int cnt,pre[N];
    
    
    void add_edge(int u,int v)
    {
        edge[cnt].to=v;
        edge[cnt].next=pre[u];
        pre[u]=cnt++;
    }
    
    int main()
    {
        //check();
        //freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
        //freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
    
    
        cnt=0;
        memset(pre,-1,sizeof(pre));
        memset(g,-1,sizeof(g));
        memset(mark,0,sizeof(mark));
        int n;
        scanf("%d",&n);
        if(n%2!=0)
        {
            printf("-1");
            return 0;
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<2;j++)
            {
                int tmp=2*i+j;
                tmp=tmp%n;
                g[i][j]=tmp;
                add_edge(tmp,i);
            }
        }
        memset(a,0,sizeof(a));
        ////////////////////////////////////////// 还是要逆过来搜索
        int a1=1,b=0;
        que[a1].push(0);
        int num=0;
        mark[0]=1;
        while(que[a1].size()!=0)
        {
            num++;
            swap(a1,b);
            while(que[b].size()!=0)
            {
                int cur=que[b].front();
                que[b].pop();
                for(int p=pre[cur];p!=-1;p=edge[p].next)
                {
                    int v=edge[p].to;
                    if(mark[v]==0)
                    {
                        mark[v]=1;
                        a[v]=num;
                        que[a1].push(v);
                    }
                }
            }
        }
    
    
        memset(mark,0,sizeof(mark));
         int cnt1=0;
         save[cnt1++]=0;
         mark[1]=1;
         save[cnt1++]=1;
         int tmp=1;
         while(1)
         {
             int tmp1=-1,id;
             for(int i=0;i<2;i++)
             {
                 if(mark[ g[tmp][i] ]==1) continue;
                 if(a[ g[tmp][i] ] > tmp1)
                 {
                     tmp1=a[ g[tmp][i] ];
                     id=g[tmp][i];
                 }
             }
             tmp=id;
             save[cnt1++]=tmp;
             mark[tmp]=1;
             if(tmp==0) break;
         }
         for(int i=0;i<cnt1;i++)
              printf("%d ",save[i]);
        // if(cnt1!=n+1)
             //printf("NO
    ");
        return 0;
    }
  • 相关阅读:
    Java并发教程(Oracle官方资料)
    java中的字符集和编码
    一篇文章看懂Java并发和线程安全
    mysql中,如何查看数据库中当前可用的校勘?字符集默认的collation?
    mysql数据库中,查看当前支持的字符集有哪些?字符集默认的collation的名字?
    mysql数据库中,通过一条insert into语句,同时插入多个值
    jenkins第一次登陆,输入完密码之后,卡在了SetupWizard[jenkins]处
    mysql数据库,如何在登录mysql之后执行操作系统上的SQL脚本?
    mysql在命令行中,指定要连接的数据库?
    mysql中如何在命令行中,执行一个SQL脚本文件?
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/3189732.html
Copyright © 2011-2022 走看看