codeforces 720A:Closing ceremony

Description

The closing ceremony of Squanch Code Cup is held in the big hall with n × m seats, arranged in n rows, m seats in a row. Each seat has two coordinates (x, y) (1 ≤ x ≤ n, 1 ≤ y ≤ m).

There are two queues of people waiting to enter the hall: k people are standing at (0, 0) and n·m - k people are standing at (0, m + 1). Each person should have a ticket for a specific seat. If person p at (x, y) has ticket for seat (xp, yp) then he should walk |x - xp| + |y - yp| to get to his seat.

Each person has a stamina — the maximum distance, that the person agrees to walk. You should find out if this is possible to distribute all n·m tickets in such a way that each person has enough stamina to get to their seat.

Input

The first line of input contains two integers n and m (1 ≤ n·m ≤ 104) — the size of the hall.

The second line contains several integers. The first integer k (0 ≤ k ≤ n·m) — the number of people at (0, 0). The following k integers indicate stamina of each person there.

The third line also contains several integers. The first integer l (l = n·m - k) — the number of people at (0, m + 1). The following l integers indicate stamina of each person there.

The stamina of the person is a positive integer less that or equal to n + m.

Output

If it is possible to distribute tickets between people in the described manner print "YES", otherwise print "NO".

Examples
Input
2 2
3 3 3 2
1 3
Output
YES
Input
2 2
3 2 3 3
1 2
Output
NO



正解:贪心
解题报告:

  因为我们想使得到两个出发点的距离小,但是不能同时保证两个,那么我们只能先保证一个最优,才想办法判断另外一个。显然把所有点按到左下角距离排序,可以对于左下角的点判断可达,然后我们每次走离左上角尽可能远的点,这样相当于是帮左上角的点分担了一部分远的点,同时可以保证合法性。

 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long LL;
15 const int MAXN = 10011;
16 int n,m,k,tot;
17 int a[MAXN];
18 struct node{
19     int x,y,z,dis;
20     bool operator < (const node &a) const{
21     return a.z>z;
22     }
23 }s[MAXN];
24 
25 priority_queue<node>Q;
26 inline int getint()
27 {
28        int w=0,q=0; char c=getchar();
29        while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 
30        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;
31 }
32 
33 inline bool cmp(node q,node qq){ return q.dis<qq.dis; }
34 
35 inline void work(){
36     n=getint(); m=getint(); k=getint();
37     for(int i=1;i<=k;i++) a[i]=getint();
38     sort(a+1,a+k+1);
39     for(int i=1;i<=n;i++)
40     for(int j=1;j<=m;j++)
41         s[++tot].x=i,s[tot].y=j,s[tot].z=m+1-j+i,s[tot].dis=i+j;
42     sort(s+1,s+tot+1,cmp); int u=1; bool ok=true;
43     
44     for(int i=1;i<=k;i++) {
45     while(a[i]>=s[u].dis && u<=tot) Q.push(s[u]),u++;
46     if(Q.empty()) { ok=false; break;  }
47     Q.pop();//清空
48     }
49     if(!ok) { printf("NO"); return; }
50     while(u<=tot) Q.push(s[u]),u++;
51 
52     k=getint(); for(int i=1;i<=k;i++)  a[i]=getint();
53     sort(a+1,a+k+1);
54     for(int i=k;i>=1;i--) {
55     if(a[i]<Q.top().z) { ok=false; break; }
56     Q.pop();
57     }
58     if(!ok) { printf("NO"); return; }
59     printf("YES");
60 }
61 
62 int main()
63 {
64   work();
65   return 0;
66 }
原文地址:https://www.cnblogs.com/ljh2000-jump/p/5883349.html