給定平面上的 n 個點, 其中有一些是紅的, 其他是藍的.現在讓你找兩條平行的直線, 使得在保證
不存在乙個藍色的點 被夾在兩條平行線之間,不經過任何乙個點, 不管是藍色點還是紅色點
的前提下,
被夾在平行線之間的紅色點個數最多
第1行: 乙個整數 n (1 <= n <= 1000)
第2..n+1行: 每行是乙個點的座標以及它的顏色.
座標用2個 絕對值<10^9
的整數表示
顏色用 'r' 或 'b' 表示
第1行: 僅乙個整數, 被夾在平行線之間的紅色點個數的最大值
40 0 r
0 1 b
1 1 r
1 0 b2
先考慮一下如果這兩條直線必須與x軸垂直怎麼做,我們先可以將所有點按x為第一關鍵字,y為第二關鍵字排序,在這個排好序的序列中找到最長的一段紅色就是答案了(用線段樹維護)
然後我們把座標系旋轉,如果y軸掃過了兩點連成的直線,則這兩個點的排名就會交換,旋轉一周交換的點對為o(n2)個,所以可以用乙個線段樹來維護區間最長紅點數,支援單點修改和查詢,複雜度o(n2logn)。
code:
1 #include2 #include3 #include4 #include5#define maxn 1005
6using
namespace
std;
7int
n,m,a,b,ans,pos[maxn];
8char s[2
]; 9 inline int min(const
int &a,const
int &b)
13 inline int max(const
int &a,const
int &b)
17struct
pointpoint[maxn];
20 inline bool
cmp1(point a,point b)
24struct
lineline[maxn*maxn];
27 inline bool cmp2(const line &a,const line &b)
28 inline bool cmp(const line &a,const line &b)
29struct
seg
39 inline void modify(int k,int l,int r,int x,int
c) 41
int m=(l+r)>>1
; 42
if (x<=m) modify(ls,l,m,x,c); else modify(rs,m+1
,r,x,c);
43update(k);
44}
45}t;
46int
main()
52 sort(point+1,point+n+1
,cmp1);
53for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++)
54 line[++m]=(line);
55 sort(line+1,line+m+1
,cmp2);
56for (int i=1;i<=n;i++) t.modify(1,1
,n,i,point[i].col);
57 ans=t.val[1
]; 58
for (int i=1,j=1;i<=m;i=j)
66}
67 printf("
%d\n
",ans);
68return0;
69 }
省隊集訓DAY6
f i 表示以字元i結尾的字串的個數。那麼現在加入乙個字元產生的貢獻就是 字 符集大小 i 0f i 然後把這個答案賦值給這個字元對應的位置。考慮這麼做會不會產生相同的串?假設acbb,考慮插入第乙個b的影響會形成ab,cb,acb.那麼插入第二個b會形成abb,cbb,acbb發現這些都是新產生的...
省隊集訓Round3 DAY6
這道題應該是可以通過組合數直接計算的,但是我不會數學證明,所以就用了一種簡單粗暴的方式。an s 2 ic n,i c n n i an s 2 ic n,i 2 101 8 肯定不能直接列舉,如果要計算的話也需要用到lucas定理。觀察發現這題的模數比較小,所以從模數入手。考慮lucas定理。n ...
省隊集訓DAY2
假設我們列舉數列中長度為len的區間,那麼如何判斷兩個數列可以匹配呢?對於提取的數列從小到大排序,從大到小排序,然後兩兩配對,如果所有的都滿足 h 那麼就可以匹配。應該算是貪心吧。這樣做的時間複雜度是o n le n loglen 還是上面的思想,我們如何快速判斷呢?假設我們確定了提取出的區間數列,...