當前位置:
首頁 >
P7045-[MCOI-03]金牌【构造,交互题】
發布時間:2023/12/3
36
豆豆
生活随笔
收集整理的這篇文章主要介紹了
P7045-[MCOI-03]金牌【构造,交互题】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/P7045?contestId=36089
題目大意
nnn個物品有一些顏色,可以詢問QQQ次兩個物品的顏色是否相同,求一個排列是的相鄰的物品顏色不同。其中Q≥2n?2Q\geq 2n-2Q≥2n?2
解題思路
對于每一個不在頭尾的物品,我們需要求出兩個與其顏色不同的物品,當我們判斷兩個物品顏色是否相同時,如果不同,那么我們就各為一個物品找到了一個顏色不同的。如果相同,假設有kkk個顏色相同的物品,那么只需要找到k+1k+1k+1個顏色與他們不同的物品,也就是沒浪費一個詢問找到相同的物品,后面就可以少用一次詢問找不同的物品。所以可以證明如果有解的話那么一定在2n?22n-22n?2次可以詢問出答案。
考慮如何實現,我們開一個棧,如果新的物品和棧頂的顏色相同,那么壓入棧中。否則在序列后面填入一個棧頂元素,如果此時棧為空那么將新的物品壓入棧中,否則直接填在后面。
對于剩下棧中的元素,我們從前面往后開始找位置填入即可。
時間復雜度O(Tn)O(Tn)O(Tn)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<stack> using namespace std; const int N=5e4+10; int T,n,Q,v[N],z[N],a[N],cnt; stack<int> s; int Ask(int x,int y){int ans;printf("%d %d\n",x-1,y-1);fflush(stdout);scanf("%d",&ans);return ans; } int main() {scanf("%d",&T);v[0]=1;while(T--){scanf("%d%d",&n,&Q);for(int i=1;i<=n;i++)v[i]=z[i]=0;while(!s.empty())s.pop(); cnt=0;s.push(1);int lim=1;for(int i=2;i<=n;i++){bool z=Ask(s.top(),i);if(z){a[++cnt]=s.top();s.pop();if(s.empty())s.push(i),lim=i;else a[++cnt]=i;}else s.push(i);}a[++cnt]=s.top();s.pop();if(s.empty()){printf("%d\n",n); for(int i=1;i<=cnt;i++)printf("%d ",a[i]-1);putchar('\n');fflush(stdout);continue;}for(int i=1;i<lim;i++){v[i]=Ask(a[i],s.top());if(v[i]&&v[i-1]){z[i]=s.top();s.pop();if(s.empty())break;}}if(!s.empty()){printf("-1\n");fflush(stdout);continue;}printf("%d\n",n);for(int i=1;i<=cnt;i++){if(z[i])printf("%d ",z[i]-1);printf("%d ",a[i]-1);}putchar('\n');fflush(stdout);} }總結
以上是生活随笔為你收集整理的P7045-[MCOI-03]金牌【构造,交互题】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P7044-[MCOI-03]括号【组合
- 下一篇: 4000游戏电脑配置推荐(4000游戏电