cogs 717. [SDOI2007] 小组队列

★★ 输入文件:team.in 输出文件:team.out 简单对比
时间限制:1 s 内存限制:128 MB

【问题描述】
队列和优先队列(用堆实现)是常用的数据结构,但是有一种小组队列却很少有人知道,
尽管在生活中经常使用。在人们素质不是很高的地方排队其实不是使用队列,而是小组队列。
在人们索质不是很高的地方,排队往往是这样的:每个人都属于一个小组,并且该小组
的人非常团结。每当一个人来排队的时候,他会先看一下前边有没有自己小组的成员,如果
有的话,他会站到自己小组最后一个成员的后边,如果没有的话,是他最倒霉的时候,他必
须站到整个队列的最后。
现在,要求写一种数据结构来模拟小组队列。
具体问题:有m个小组, n 个元素(编号 0..n-1 ) ,每个元素属于一个小组,当元素 k
进入队列时,如果前边有 k 所属小组的元素,k 会排到自己小组最后一个元素的下一个位
置,否则 k 排到整个队列最后的位置。出队的方式和普通的队列相同,即排在前边的元素先出队。
注:每个元素可能进出队列多次。进出队列的命令最多 100 000 个。
【输入】(team.in)
第一行m (m<= 300)
以下 m 行,每行表示一个小组。每行开始有一个 k 表示该组的元素个数(1 <= k <=总
元素个数),接下来 k 个数,每个数表示该组的一个元素的编号。
以下若干行(以"STOP"结束),每行有“ENQUEUE k” 或“DEQUEUE”,前者表示元素 k 进队,后者表示队头的元素出队。
【输出】(team.out)
对应每个出队命令,按出队顺序依次输出出队的元素,每个一行。
【样例输入】
4
4 0 1 2 3
4 4 5 6 7
4 8 9 10 11
4 12 13 14 15
ENQUEUE 6
ENQUEUE 14
ENQUEUE 1
ENQUEUE 11
ENQUEUE 2
ENQUEUE 4
ENQUEUE 13
ENQUEUE 15
ENQUEUE 12
ENQUEUE 7
ENQUEUE 9
ENQUEUE 10
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
ENQUEUE 8
ENQUEUE 12
ENQUEUE 6
ENQUEUE 3
ENQUEUE 5
ENQUEUE 1
ENQUEUE 4
ENQUEUE 15
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
STOP
【样例输出】


6
4
7
14
13
15
12
1
2
3
1
11
9
10
8
12
15
6
5
4
范围说明:前30% 1<=n<=100 1<=m<=10 进出队命令<=50


全部 1<=n<=100 000 1<=m<=300 命令<=100 000

 

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
 
using namespace std;
const int N=100001;
const int M=310;
 
queue<int>every_group[M];
queue<int>name_group;
int belong[N];
int k,G,member,add,belong_group,top_group,answer;
string how;
bool vis[M];
 
int read()
{
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    return x;
}
 
 
int main()
{
    freopen("team.in","r",stdin);
    freopen("team.out","w",stdout);
    
    G=read();
    for(int i=1;i<=G;i++)
    {
        k=read();
        for(int j=1;j<=k;j++)
        {
            member=read();
            belong[member]=i;
        }
    }
    while(1)
    {
        cin>>how;
        if(how=="STOP")
            return 0;
        if(how[0]=='E')
        {
            add=read();
            belong_group=belong[add];
            if(!vis[belong_group])
            {
                name_group.push(belong_group);
                vis[belong_group]=1;
            }
            every_group[belong_group].push(add);
        }
        else
        {
            top_group=name_group.front();
            answer=every_group[top_group].front();
            every_group[top_group].pop();
            if(every_group[top_group].empty())
            {
                name_group.pop();
                vis[top_group]=0;
            }    
            printf("%d\n",answer);
        }
    }
    
    return 0;    
}

 

转载于:https://www.cnblogs.com/lyqlyq/p/7095591.html

以下是将代码修改为cot平滑的方法: 1. 首先,需要使用边界角的cot权重计算每个顶点的权重。 2. 然后,使用cot权重对每个顶点的邻域点进行加权计算,得到平滑后的坐标。 3. 最后,根据平滑后的坐标更新每个顶点的位置。 修改后的代码如下: float smooth() { float err = -1; cogs.clear(); v_end = mesh.vertices_end(); //cot平滑 for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) { cog[0] = cog[1] = cog[2] = weight_sum = 0.0; for (vv_it = mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) { double cot_weight = 0.0; MyMesh::HalfedgeHandle heh = mesh.find_halfedge(*v_it, *vv_it); if (!mesh.is_boundary(heh)) { MyMesh::HalfedgeHandle prev_heh = mesh.prev_halfedge_handle(heh); MyMesh::HalfedgeHandle next_heh = mesh.next_halfedge_handle(heh); MyMesh::VertexHandle prev_vh = mesh.to_vertex_handle(prev_heh); MyMesh::VertexHandle next_vh = mesh.to_vertex_handle(next_heh); MyMesh::Point prev_p = mesh.point(prev_vh); MyMesh::Point curr_p = mesh.point(*v_it); MyMesh::Point next_p = mesh.point(next_vh); double cot_alpha = cot(prev_p - curr_p, next_p - curr_p); double cot_beta = cot(curr_p - prev_p, next_p - prev_p); cot_weight = cot_alpha + cot_beta; } cog += cot_weight * mesh.point(*vv_it); weight_sum += cot_weight; } cogs.push_back(cog / weight_sum); } for (v_it = mesh.vertices_begin(), cog_it = cogs.begin(); v_it != v_end; ++v_it, ++cog_it) { if (!mesh.is_boundary(*v_it)) { MyMesh::Point p = mesh.point(*v_it); err = max(err, (p - *cog_it).norm()); mesh.set_point(*v_it, *cog_it); } } return err; } 其中cot函数的定义如下: double cot(MyMesh::Point a, MyMesh::Point b) { return dot(a, b) / cross(a, b).norm(); } 注意,这里使用的是边界角的cot权重,因此在计算cot权重时需要判断当前边是否为边界。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值