日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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-2Q2n?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]金牌【构造,交互题】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。