netbeans 小便池算法-简单优化

mpgws1up  于 2022-11-10  发布在  其他
关注(0)|答案(5)|浏览(177)

我 是 一 个 编程 二 的 学生 和 第 一 次 海报 第 一 次 海报 。 什么 很 可能 是 一 个 非常 简单 的 问题 已经 困扰 了 我 太 久 。
[ 3 ] 问题 3 : 经过 充分 研究 发现 , 在 洗手 间 里 的 男性 通常 更 喜欢 占据 最 长 的 空位 序列 的 中间 位置 , 从而 最 大 限度 地 远离 已经 被 占用 的 隔间 , 例如 , 假设 有 10 个 隔间 是 空 的 。
第 一 位 访客 将 占据 中间 位置 :
第 _ _ _ _ _ 次
下 一 位 参观 者 将 在 左边 空白 区域 的 中间 。
X 月 X 日
用 Java 编写 一 个 程序 , 读取 停车 位 的 数量 , 然后 按照 上面 给出 的 格式 打印 出 停车 位 填满 时 的 图表 , 一 次 打印 一 个 。 提示 :使用 布尔 值 数组 指示 暂停 是否 已 被 占用 。

public class MenStall
{
public static int nextStall(boolean[] stalls) { . . . }
public static void printStalls(boolean[] stalls) {. . . }
. . .
}

中 的 每 一 个
失速 数 = 10 时 的 输出 示例
第 _ _ _ _ _ _ _ _ 次
第 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
X X X X
X X X
X X X
X X X X
_ X X _ X X _ X X X
_ X X _ X X X X X X X
_ X X X X X X X X X
X X X X X X X X X X
我 以为 最 简单 的 方法( 这 学期 我们 学到 了 一 点 编程 知识 ) 要 做到 这 一 点 , 需要 声明 数组 的 结尾 和 开头 为 变量 , 然后 通过 从 结尾 减去 开头 再 除以 2 来 找到 中间 。 不幸 的 是 , 除 此 之外 我 就 卡住 了 。 我 对 编码 术语 不 太 精通 ,因此 , 我 为此 道歉 。 我 想 , 更 简单 的 做法 是 表明 我 试图 解决 这个 问题 :

public class MenStall

{

public static int position = 0;
public static int nextStall = 0;
public static boolean[] stalls = new boolean[10];
public static final int TRUE_END = stalls.length;
public static final int TRUE_START = 0;
public static int start = TRUE_START;
public static int end = TRUE_END;
public static final int TRUE_MID = (TRUE_END - TRUE_START) / 2;
public static int mid = TRUE_MID;

public static int nextStall(boolean[] stalls) 
{  
    if (position == 0)
    {
        nextStall = mid;
    }
    else
    {
        if (position % 2 == 1)
        {
            end = mid;
            mid = (end - start) / 2;
            nextStall = mid;
        }

        else if (position % 2 == 0)
        {
            mid = (end - start) / 2 + TRUE_MID;
            nextStall = mid;
            end = mid;
            mid = (TRUE_END - TRUE_START) / (int)Math.pow(2,position);

        }
    }

    position++;
    return nextStall;
}

public static void printStalls(boolean[] stalls) 
{
    String[] s1 = new String[stalls.length];

    while (position < stalls.length)
    {
        nextStall(stalls);
        stalls [nextStall] = true;
        for (int i = 0; i < stalls.length; i++)
        {
            if(stalls[i] == true)
            {
                s1[i] = "x";
            }
            else
            {
                s1[i] = "_";
            }
        }
    System.out.println(Arrays.toString(s1));
    }     
}

public static void main(String[] args) 
{
    printStalls(stalls);
}

}

格式
在 nextStall 方法 的 最 后 , 我 几乎 只是 在 玩 我 是 如何 陷入 困境 的 数字 。 我 当然 付出 了 我 最 认真 的 努力 , 甚至 不得 不 请求 教授 延长 , 但 我 无法 为 我 的 生活 弄 清楚 这 一 点 。 任何 指导 将 不胜 感激 。 谢谢 !

rkttyhzu

rkttyhzu1#

在我看来,使用BitSet比使用boolean[]数组要简单,因为BitSet有一个预定义的方法nextSetBit,它返回(正如它的名字所说)下一个集合位。我认为,对于你的任务来说,分治策略是不必要的。问题可以这样解决:

public static void main(String[] args) {
    int numStalls = 10; // get it from user input if you like
    BitSet bs = new BitSet();
    // set the leftmost and the rightmost bits (which represent walls)
    bs.set(0);
    bs.set(numStalls+1);
    // now we have 10 bits gap, which represent stalls
    // like this: X__________X
    for(int i=0; i<numStalls; i++) {
        bs.set(nextStall(bs));
        printStalls(bs);
    }
}

public static int nextStall(BitSet bs) {
    int bestPos = 0, maxDist = bs.nextSetBit(0);
    // iterate over the set bits
    for(int pos = maxDist; pos != -1; pos = bs.nextSetBit(pos+1)) {
        int dist = bs.nextSetBit(pos+1) - pos;
        // track the position of the stall with biggest gap on the right
        if(dist > maxDist) {
            maxDist = dist;
            bestPos = pos;
        }
    }
    // return the position on the middle of the best gap
    return bestPos+maxDist/2;
}

public static void printStalls(BitSet bs) {
    StringBuilder sb = new StringBuilder();
    // Iterate over all the bit positions except the walls
    // walls have positions 0 and bs.length()
    for(int i=1; i<bs.length()-1; i++) {
        sb.append(bs.get(i) ? "X" : "_");
    }
    System.out.println(sb);
}

如果允许使用Java-8,则解决方案可以更短:

public static int nextStall(BitSet bs) {
    // Find the position of the stall (or wall)
    // For which the next stall/wall is the most distant
    // bs.stream() returns stream of positions of the set bits
    int pos = bs.stream().boxed()
                .max(Comparator.comparingInt(v -> bs.nextSetBit(v+1) - v)).get();
    // Return the middle position in the gap
    return (pos+bs.nextSetBit(pos+1))/2;
}

public static void printStalls(BitSet bs) {
    // Iterate over all the bit positions except the walls
    // walls have positions 0 and bs.length()
    System.out.println(IntStream.range(1, bs.length() - 1)
            .mapToObj(idx -> bs.get(idx) ? "X" : "_").collect(Collectors.joining()));
}
j91ykkif

j91ykkif2#

使用优先级队列解决此问题的C++解决方案


# include<iostream>

# include<bits/stdc++.h>

using namespace std;
struct s
{
    int distance;
    int start;
    int ending;
};
struct fn
{
    bool operator()(s const&a,s const &b)
    {
        if(a.distance!=b.distance)
        {
            return a.distance<b.distance;
        }
        return a.start<b.start;
    }
};
int main()
{
    int n;
    cin >> n;
    int mat[n] = {0};
    priority_queue<s,vector<s>,fn> q;
    struct s temp;
    int l=1,r=n,coun=1;
    q.push({n,l,r});
    while(!q.empty())
    {
        temp = q.top();
        q.pop();
        int left = temp.start;
        int right = temp.ending;
        int mid = (left+right)/2;
        if(temp.distance>0)
        {
            if(right>mid)
            {
                q.push({right-mid,mid+1,right}); // first push right child then left
            }
            if(left<mid)
            {
                q.push({mid-left,left,mid-1});
            }
        }
        mat[mid-1] = coun;
        coun++;
        for(int i=0; i<n; i++)
        {
            if(mat[i]==0)
            {
                cout << "_" << " ";
            }
            else
            {
                cout << "X" << " ";
            }

        }
        cout << endl;
    }

}
cl25kdpy

cl25kdpy3#

我想这应该可以。

import java.util.*;

public class hinata {
static Scanner scan = new Scanner(System.in);
public static void main(String[] args){
    bfs(5,10);
}
static class node{int left, right,level; node(int left, int right, int level){this.left=left;this.right=right;this.level=level;}}
public static void bfs(int lev, int n){
    LinkedList<node> queue = new LinkedList<>(); boolean[] arr = new boolean[n];
    queue.addLast(new node(0,n-1,lev));
    int e = lev;
    while(!queue.isEmpty()){
        node curr = queue.removeLast();
        int l = curr.left, r = curr.right;
        if(e <= 0){break;}
        else{
            int mid = (l+r)>>1; arr[mid] = true;
            System.out.print(e+" : ");print(arr);
            --e;
            if(mid+1 <=r){
                queue.addFirst(new node(mid+1,r,e));
            }

            if(l <=mid-1){
                queue.addFirst(new node(l, mid-1,e));
            }
        }
    }
}

static void print(boolean[] arr){
    for(boolean i : arr){
        if(!i){System.out.print('_');}
        else{System.out.print('X');}
    }System.out.println();
}

}
zc0qhyus

zc0qhyus4#

这看起来类似于二叉树的层次顺序遍历,也就是说,在每一层,你把问题进一步分成两个子问题。
所以我的意思是,假设最初,你有l=0,r=n-1,其中n是输入的大小或小便池的数量。
然后你要做的就是取mid =(l+r)/2,在那里放一个人,然后把(l,mid-1)和(mid+1,r)推到队列中。
重复此过程,直到所需的小便池已装满。

kcugc4gi

kcugc4gi5#

下面是同样的C++代码!


# include <iostream>

# include<bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin>>n;
    string s="";
    for(int i=0; i<n; i++){
        s+="_";
    }

    priority_queue<pair<int, int>> pq;
    pq.push({n,0});
    for( int i=0; i<n; i++){
        pair<int, int> front= pq.top();
        pq.pop();
        int indx= (front.first-1)/2+ front.second;
        s[indx]= 'X';
        cout<<s<<endl;
        pq.push({indx- front.second, front.second});
        pq.push({front.first/2, indx+1});
    }
    return 0;

}

相关问题