我们部门需要装饰墙,但是墙非常非常的长,有一千万米。我们会按顺序贴很多海报在上面,这些海报相互之间会重叠,请问下,最后还能看到哪些?(只看到一部分也算)
N表示N张海报
接下来每一行代表海报的左右边界(上下默认全满),Li,Ri,均为整数,大于0,小于一千万。海报按输入顺序张贴。
有多少张海报是可见的
5 1 4 2 6 8 10 3 4 7 10
4
#优化过的顺序dp插入判断方法,很好理解,百分百通过 def main(): N = int(input()) k = [[0, i, -1] for i in range(N*2)] maxs = 0 i = 0 while i < N*2: a, b = map(int, input().split()) k[i][0] = a k[i+1][0] = b i += 2 # print(k) k.sort(key=lambda x:x[0]) k[0][2] = 0 count = 0 for i in range(1, len(k)): if k[i][2] == k[i-1][2]: k[i][2] = count else: count += 1 k[i][2] = count # print("count", count) dp = [-1] * (count+1) # print(k) k.sort(key=lambda x:x[1]) # print(k) i = 0 # print(dp) while i < len(k): left = k[i][2] right = k[i+1][2] for j in range(left, right+1, 1): dp[j] = i i += 2 # print(dp) dic = dict() for i in range(len(k)): dic[dp[i]] = dic.get(dp[i], 0)+1 # print(dic) print(len(dic)) if __name__ == "__main__": main()
import sys n=int(input()) data=[] for i in range(n): data.append(list(map(int,sys.stdin.readline().strip().split()))) res=[0]*10000000#给每个单位区间段一个编号,海报覆盖就相当于重叠,重新赋值一段海报长度的一样的编号 for i in range(1,n+1): res[data[i-1][0]:data[i-1][1]]=[i]*(data[i-1][1]-data[i-1][0]) res=set(res) ress=len(res)-1 print(ress)
""" 一个实现起来很简单的思路,通过80%用例,考试时很实用,不知道改成C或java是不是还超时 对于示例1,所有左右边界组成的集合(1, 2, 3, 4, 6, 7, 8, 10),分成七段; 借助字典从前到后为每一段赋值海报编号, 最后 每一段的值代表最上边可以看到的海报编号, 对字典的值求集合的长度,即为可见海报的张数 """ import sys if __name__ == "__main__": # sys.stdin = open("input.txt", "r") n = int(input().strip()) a = [] for _ in range(n): a.append(list(map(int, input().strip().split()))) b = sorted(list(set(sum(a, [])))) d = dict() for i in range(n): for j in range(b.index(a[i][0]), b.index(a[i][1])): d[str(b[j]) + '-' + str(b[j + 1])] = i ans = len(set(d.values())) print(ans)
/* 对每一张海报t, 计算上一层海报未覆盖的(可见)区域(x,y), 递归调用,直到t>n,海报t仍可以被看到,返回True; 或者直到某一层将可见区域完全覆盖,返回False。 by the way: 最后一个测试用例是错的吧,通过仔细对比已通过程序,26行改为27行通过全部用例 */ #include<bits/stdc++.h> using namespace std; #define N 10000 int n; int a[N][2]; bool cover(int x, int y, int t) { if (x >= y) return false; if (t >= n) return true; if (a[t][0] <= x && y <= a[t][1]) return false; else if (a[t][0] >= y || a[t][1] <= x) return cover(x, y, t + 1); else if (x <= a[t][0] && a[t][1] <= y) // return cover(x, a[t][0], t + 1) || cover(a[t][1], y, t + 1) return cover(x, y, t + 1); else if (x < a[t][1] && a[t][1] < y) return cover( a[t][1], y, t + 1); else if (x < a[t][0] && a[t][0] < y) return cover( x, a[t][0], t + 1); return false;//所有情况都考虑到了,此句不需要;删除此句有时会编译不通过 } int main() { // freopen("input.txt", "r", stdin); cin >> n; for(int i = 0; i < n; i++) { cin >> a[i][0] >> a[i][1]; } int ans = 0; for(int t = 0; t < n; t++) if(cover(a[t][0], a[t][1], t + 1)) ans += 1; cout << ans << endl; return 0; }