C:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3573
瞎搞题,可以用线段树+lazy过。CB曾经出过一个类似的,可以0(N)的处理。左边加右边减,边走边算。
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
const int maxn = 15100;
using namespace std;
LL f[maxn];
LL p[maxn];
LL k[maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
int x, y, z;
memset(f, 0, sizeof(f));
memset(p, 0, sizeof(p));
memset(k, 0, sizeof(k));
while(~scanf("%d %d %d",&x, &y, &z))
{
if(x == -1) break;
f[x] += z;
p[y+1] -= z;
}
int lmax;
LL Max = -1LL;
LL xmax = 0LL;
for(int i = 0; i <= n; i++)
{
xmax += f[i]+p[i];
k[i] = xmax;
if(xmax > Max)
{
Max = xmax;
lmax = i;
}
}
int rmax;
for(int i = n; i >= 0; i--)
{
if(k[i] == Max)
{
rmax = i;
break;
}
}
cout<<lmax<<" "<<rmax<<endl;
}
return 0;
}
D:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3574
这道题目感觉挺好的,求在两个直线之间的所有线段的交点。一开始的想法是左右分别排序根据差值算出交点,但是排序好像有问题。后来改成按右边的y值排序再求出逆序数就可以了啊。
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <map>
#include <set>
#define eps 1e-12
///#define M 1000100
///#define LL __int64
#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)
using namespace std;
const int maxn = 30100;
LL sum;
struct node
{
LL y1;
LL y2;
int id;
};
node a[maxn], temp[maxn];
void Merge(node a[], int l, int mid, int r)
{
int begin1 = l;
int end1 = mid;
int begin2 = mid+1;
int end2 = r;
int k = 0;
while(begin1 <= end1 && begin2 <= end2)
{
if(a[begin1].y1 < a[begin2].y1)
{
temp[k++] = a[begin1];
begin1++;
sum += begin2-(mid+1);
}
else
{
temp[k++] = a[begin2];
begin2++;
}
}
while(begin1 <= end1)
{
temp[k++] = a[begin1];
begin1++;
sum += end2-mid;
}
while(begin2 <= end2)
{
temp[k++] = a[begin2];
begin2++;
}
for(int i = l; i <= r; i++) a[i] = temp[i-l];
}
void MergeSort(node a[], int l, int r)
{
int mid = (l+r)>>1;
if(l < r)
{
MergeSort(a, l, mid);
MergeSort(a, mid+1, r);
Merge(a, l, mid, r);
}
}
bool cmp(node a, node b)
{
return a.y2 < b.y2;
}
int main()
{
LL x1, x2;
while(~scanf("%lld %lld",&x1, &x2))
{
int n;
scanf("%d",&n);
if(n == 0)
{
cout<<1<<endl;
continue;
}
LL k, b;
for(int i = 0; i < n; i++)
{
scanf("%lld %lld",&k, &b);
a[i].y1 = k*x1+b;
a[i].y2 = k*x2+b;
}
sort(a, a+n, cmp);
sum = 0;
MergeSort(a, 0, n-1);
cout<<sum+n+1<<endl;
}
return 0;
}
F:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4598
这个题目是瞎猜了一下,把它转化为两个互质的模型后求出来百分比,用总的长度乘以百分比就可以了啊。
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
const int maxn = 30010;
using namespace std;
int main()
{
LL n, m;
while(~scanf("%lld %lld",&n, &m))
{
double x = sqrt(n*n*1.0+m*m*1.0);
LL p = __gcd(n, m);
m /= p;
n /= p;
p = m*n;
LL xx = p/2;
if(p%2) xx++;
double y = (xx*1.0)/p;
printf("%.6lf\n",x*y);
}
return 0;
}
H:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3578
n很小可以暴力判断每次操作之后所在区域的最大值,然后加上h就是总的结果。最后求出一个最大值就可以了。
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
const int maxn = 15100;
using namespace std;
struct node
{
int h;
int H;
int a, b, x, y;
}f[maxn];
bool judge(int x, int y)
{
if(f[x].x+f[x].a <= f[y].x || f[y].x+f[y].a <= f[x].x) return false;
if(f[x].y+f[x].b <= f[y].y || f[y].y+f[y].b <= f[x].y) return false;
return true;
}
int main()
{
int n, m, c;
while(~scanf("%d %d %d",&n, &m, &c))
{
for(int i = 0; i < c; i++)
{
scanf("%d %d %d %d %d",&f[i].a, &f[i].b, &f[i].h, &f[i].x, &f[i].y);
f[i].H = 0;
for(int k = 0; k < i; k++)
if(judge(i, k)) f[i].H = max(f[i].H, f[k].H);
f[i].H += f[i].h;
}
int Max = -1;
for(int i = 0; i < c; i++) Max = max(Max, f[i].H);
cout<<Max<<endl;
}
return 0;
}