usaco 猜數遊戲

2022-06-02 10:09:10 字數 1899 閱讀 5065

為了提高智商,鍛鍊思維能力,奶牛設計了乙個猜數遊戲。遊戲開始前,貝西會在牛棚後面擺上n個數字。所有數字排成一條直線,按次序從1到n編號。每個數字在1到10^9之間,沒有兩個數字是一樣的。

遊戲開始後,其他奶牛將會輪流詢問貝西q個問題,每個問題的格式都是一樣的:

「位置在ql到qr的數字中,最小的數字是多少?」

對每個問題,貝西都會回答乙個數字a,不過,她的回答可能是不正確的。請你幫助其他奶牛判斷一下,貝西從**開始已經出現矛盾了。

第一行:兩個用空格分開的整數:n和q,1 ≤ n ≤ 106,1 ≤ q ≤ 25000

第二行到第q + 1行:每行三個用空格分開的整數,ql,qr和a,表示乙個查詢,1 ≤ ql ≤ qh ≤ n

第一行:如果完全沒有矛盾,輸出0,否則輸出最先造成矛盾的查詢編號

正解 = 找規律+並查集

orz 神大胖指導。

正如題目所說,這 n 個數中不會有重複的,

因此對於相同的值的詢問如果不存在交集便是乙個矛盾,

如果存在交集,那這個數必然就在這個區間中,

但如果之前的詢問已覆蓋了這個區間

a:如果詢問值比該數小,這是種合法情況,

因為之前的詢問還能覆蓋該區間外的地方,

b:如果詢問值比該數大,顯然矛盾.

得到乙個判斷一段查詢是否合法的演算法:

將所給的詢問按數值排序(從大到小),

對於同個數值進行合併操作, 

如不存在交集 =>存在矛盾

否則對詢問交集中是否已被在比該數值大的值所覆蓋,

由於已經按從小到大排過序,如果交集中有值必然比該數值大

所以,如果區間中不存在未覆蓋的位置 = > 存在矛盾

否則說明至此未產生矛盾:

對於該同數值的詢問的並集中未覆蓋的部分進行覆蓋

如果進行完所有操作未發現矛盾,則該區間不存在矛盾.

由於僅對區間中的未覆蓋的位置進行查詢及修改,可以用並查集進行加速.

在上述演算法的基礎上,我們可以對矛盾區間進行二分查詢,不難得到答案.

ps.筆者打的遞迴並查集爆(w)棧(t)了(f),不能忍,該模擬棧了- =.

**如下:

1 #include2 #include3 #include4 #include

5 #include6 #include7

#define inf 99999999

8#define min(x,y) if(x>y) x=y

9#define max(x,y) if(x10

#define n 1000122

11#define m 25022

12using

namespace

std;

13int

f[n],n,q,mid,ans;

14int

q[n];

15struct

querya[m],b[m];

18bool cmp(const query&x,const query&y)

21int find(int

now)

29while(tail) f[q[tail--]]=now;

30return

now;31}

32bool

check()

47if(find(l)>r) return

false;48

for(int k=find(min);k<=max;k=f[k])

49 f[k]=find(k+1

);50}51

return

true

; 52}53

intmain() else le=mid+1;64

}65 printf("%d"

,ans);

66 }

view code

1995猜數遊戲

猜數遊戲 time limit 1 seconds memory limit 32768 k total submit 70 accepted 11 description 我們經常看到這樣的遊戲,機器隨機產生乙個4個不同的數字,然後你輸入4個不同數字,然後機器自動判斷你輸入的4個數字有多少個數字猜...

簡單猜數遊戲

2.計算機隨機生成乙個1024之內的整數,請你猜這個數,如果猜錯了,計算機會提示你大了還是小了,你一共只有十次機會,如果十次沒猜到 則提示 失敗 如果十次之內猜對則提示 你真聰明 c using system using system.collections.generic using system...

猜數遊戲 plus

猜數遊戲大家應該都不陌生,隨機產生乙個數,然後讓玩家去猜這個數的大小,但是傳統的猜數遊戲只是單純的猜數,沒有時間或者次數的限制,導致遊戲的豐富度不高 所以在傳統猜數遊戲的基礎上可以進行功能的增添,給予玩家更好的遊戲體驗 我們可以利用gettickcount 函式進行時間上的把控,可以在時間上進行限制...