#想請問neoj上的題目-中國人排隊問題
1 messages · Page 1 of 1 (latest)
等窩一下
我打一下我的作法
題目簡述:有一堆人要排隊,其中有一些人是「同夥的」,而一團同夥的人成為「一團」人。在一個人要排進隊伍時,如果在隊伍中他有「同夥」,他可以要求「給個方便」,而直接排在他的同夥們後面,如果他沒有同夥,那他只能乖乖從最後開始排隊。
我的解法:因為一個人不會隸屬兩團中國人,所以我想到並查集,於是我開了一個陣列dsu,紀錄每個人在哪一團。然後我開了一個長度為1010的queue陣列(以arr,heads,tails三個陣列和head,tail兩個變數實作),在一個人要進入隊伍前,我會先判斷隊伍中有沒有人跟他是同夥的(我開了另一個陣列place,index代表某團,而index的值代表這團在queue陣列中的位置),如果有(place中,以這個人隸屬的團為index,其值不是-1),我就往queue陣列中對應的queue(queue陣列的index為place中,以這個人隸屬的團為index的值)塞入這個人,如果沒有(place中,以這個人隸屬的團為index,其值是-1),那我就把這個人塞入有塞人的所有queue的後一個queue(tail會紀錄queue陣列中有塞人的所有queue後一個queue的位置),並且在place中,以這個人隸屬的團為index,紀錄這個在queue陣列中塞入的位置,最後tail增加1,指到下一個沒有塞人的queue。當前面的人要離開隊伍時,先輸出queue陣列中最前面的人的位置,如果queue陣列中最前面的人所屬的queue只有一個人,輸出後,head增加1,代表往下一個陣列當最前面人隸屬的queue。
#include<bits/stdc++.h>
using namespace std;
int dsu[1000010];
//queue in queue
//queue<int> arr[1010];//representing the line where people in
int arr[1100010];
int heads[1010],tails[1010];
int head=0,tail=0;
//representing where the group in line,index represent group,value represent place
int place[1010];
void push(int a){
int group=dsu[a];
if(place[group]==-1){
place[group]=tail++;
}
if(tail==1005)tail=0;
arr[tails[place[group]]]=a;
tails[place[group]]++;
return;
}
void pop(){
if(heads[head]+1==tails[head]){
place[dsu[arr[heads[head] ] ] ]=-1;
cout<<arr[heads[head] ]<<"\n";
heads[head]=0+head*1010;
tails[head]=0+head*1010;
head++;
//heads[head]++;
}else{
cout<<arr[heads[head] ]<<"\n";
heads[head]++;
//arr[head].pop();
}
if(head==1005)head=0;
}
void solve(){
//refill the place and arr
for(int i=0;i<1010;i++){
place[i]=-1;
heads[i]=0+i*1010;
tails[i]=0+i*1010;
}
/*
for(int i=0;i<1010;i++){
if(arr[i].size()>0)place[dsu[arr[i].front()]]=-1;
while(arr[i].size()>0)arr[i].pop();
}
*/
int n;
cin>>n;
//allocating people in groups
for(int i=1;i<=n;i++){
int m;
cin>>m;
for(int j=0;j<m;j++){
int tmp;
cin>>tmp;
dsu[tmp]=i;
}
}
cin>>n;
for(int i=0;i<n;i++){
string tmp;
cin>>tmp;
if(tmp=="ENQUEUE"){
int a;
cin>>a;
push(a);
}else{
pop();
}
}
return;
}
int main(){
cin.tie(0);
ios_base::sync_with_stdio(false);
int t;
cin>>t;
int a=0;
while(a!=t){
cout<<"Line #"<<a+1<<"\n";
solve();
a++;
}
return 0;
}
我這題一直卡WA
但是我找不到bug qq
怎麼說?
你是說用陣列包一堆queue,然後陣列兩個變數紀錄陣列裡最前面有塞人的queue和最後面有塞人的queue嗎?
對
我剛剛突然想到
會不會是我的輸出整理錯誤
最後面要少一個換行
但是
還是錯(
#include<bits/stdc++.h>
using namespace std;
int dsu[1000010];
//queue in queue
//queue<int> arr[1010];//representing the line where people in
int arr[1100010];
int heads[1010],tails[1010];
int head=0,tail=0;
//representing where the group in line,index represent group,value represent place
int place[1010];
void push(int a){
int group=dsu[a];
if(place[group]==-1){
place[group]=tail++;
}
if(tail==1005)tail=0;
arr[tails[place[group]]]=a;
tails[place[group]]++;
return;
}
void pop(){
if(heads[head]+1==tails[head]){
place[dsu[arr[heads[head] ] ] ]=-1;
cout<<"\n"<<arr[heads[head] ];
heads[head]=0+head*1010;
tails[head]=0+head*1010;
head++;
//heads[head]++;
}else{
cout<<"\n"<<arr[heads[head] ];
heads[head]++;
//arr[head].pop();
}
if(head==1005)head=0;
}
void solve(){
//refill the place and arr
for(int i=0;i<1010;i++){
place[i]=-1;
heads[i]=0+i*1010;
tails[i]=0+i*1010;
}
/*
for(int i=0;i<1010;i++){
if(arr[i].size()>0)place[dsu[arr[i].front()]]=-1;
while(arr[i].size()>0)arr[i].pop();
}
*/
int n;
cin>>n;
//allocating people in groups
for(int i=1;i<=n;i++){
int m;
cin>>m;
for(int j=0;j<m;j++){
int tmp;
cin>>tmp;
dsu[tmp]=i;
}
}
cin>>n;
for(int i=0;i<n;i++){
string tmp;
cin>>tmp;
if(tmp=="ENQUEUE"){
int a;
cin>>a;
push(a);
}else{
pop();
}
}
return;
}
int main(){
cin.tie(0);
ios_base::sync_with_stdio(false);
int t;
cin>>t;
int a=0;
bool door=false;
while(a!=t){
if(door)cout<<"\n";
door=true;
cout<<"Line #"<<a+1;
solve();
a++;
}
return 0;
}
改過的程式碼
草,我眼殘
我剛剛叫你重看範測,然後才發現是自己看錯題目

AC了
這題的題目也是挺可怕的ㄟ
我一開始只發現你的程式若上一次輸入中沒有讓所有排隊的人都有離開隊伍(拿到公仔),那下一次詢問就會出錯
結果改了沒過,我去看了一下這題的提交狀況,幾乎所有都是WA
所以我猜可能是題目有陷阱或者大家會不小心預設某種前提之類的
結果就發現問題了
我覺得挺有趣的你可以自己找找看(範測的第一筆資測可以看出問題
for(int i=0;i<1010;i++){
place[i]=-1;
heads[i]=0+i*1010;
tails[i]=0+i*1010;
}
備註:這個是用來清空queue陣列的
問題應該是你的head跟tail吧
跑這組可以看出來
2
1
1 1
1
ENQUEUE 1
1
1 2
2
ENQUEUE 2
DEQUEUE

