C
容斥原理,用白色的面积减去两个黑色与白色相交的面积,再加上 黑黑白 相交的面积,
第一次只减了 黑黑相交的面积,WA到第11个点,才发现,黑黑相交的面积可能不在白色的面积之内,
所以要 黑黑白的面积一起算交集,然后在减去。。终于A了。
两个矩形的面积交,可以选 左边最大的点,右边最小的点,上边最小的点,下边最大的点。
n 个矩形面积交,选出 n 个矩形当中左边最大的点,右边最小的点,上边最小的点,下边最大的点。
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-5;
typedef long long ll;
struct Point{
ll x[5],y[5];
}p[4];
ll calc(Point a,Point b){
ll lx = max(a.x[1],b.x[1]),rx = min(a.x[2],b.x[2]),
dy = max(a.y[1],b.y[1]),uy = min(a.y[2],b.y[2]);
if(lx < rx && dy < uy){
return (rx - lx) * (uy - dy);
}
else return 0;
}
ll f(Point a,Point b,Point c){
ll lx = max(a.x[1],max(b.x[1],c.x[1])),rx = min(a.x[2],min(b.x[2],c.x[2])),
dy = max(a.y[1],max(b.y[1],c.y[1])),uy = min(a.y[2],min(b.y[2],c.y[2]));
if(lx < rx && dy < uy){
return (rx - lx) * (uy - dy);
}
else return 0;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
for(int i = 1;i <= 3; ++i){
cin >> p[i].x[1]>>p[i].y[1]>>p[i].x[2]>>p[i].y[2];
}
ll c13 = calc(p[1],p[3]),c12 = calc(p[1],p[2]),c23 = f(p[1],p[2],p[3]),
W = (p[1].x[2] - p[1].x[1]) * (p[1].y[2] - p[1].y[1]);
ll m = (c13 + c12 - c23);
if(W > m) cout << "YES";
else cout << "NO";
return 0;
}
E1
原题 POJ 1019,题一样,思路也一样。
在CF AC榜里看到有大佬的写法超级简单,就学了一哈
把每个子段分成以 1 开头的序列,1,12,123,1234,12345
这样,(tmp) 是从 1 开始一直递增的string 序列,(st)代表前面已经跳过的子段
目的是要$ st + tmp.size() geq k $,这时,说明 (st leq k leq tmp.size()) ,
因为 st 一直记录的是 每个子段 开头的 1 的下标,
那么,用 (k - st) 就代表了,(k) 在 (tmp) 这一段中的下标位置,因为 string 从0开始计数,所以 (k--)
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int q,k;
cin >> q;
while(q--){
cin >> k;
string tmp = "1";
int num = 1,st = 0;
while(st + tmp.size() < k){
st += tmp.size();
num++;
tmp += to_string(num);
}
if(st) k -= st;
k--;
cout << tmp[k] << endl;
}
return 0;
}