poj1113 Wall
题意: 略。
思路:求凸包。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
const int mod = 1e9+7;
#define ll long long
#define llu unsigned long long
using namespace std;
map<string,int>mp;
const int maxn = 100550+10;
const double eps = 0.0000001;
const double PI = 3.1415926;
int v[maxn],a[maxn];
struct Point {
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
};
int n;
Point p[1150],s[1150]; //一开始数组开小了,wa了好几次。
double cross(Point a,Point b,Point c) {
return ((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
}
double dis(Point a,Point b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(Point a,Point b) {
if(a.x != b.x) return a.x<b.x;
else return a.y<b.y;
}
bool cmp1(Point a,Point b) {
double m = cross(p[0],a,b);
if(fabs(m-0.0) <= eps) {
if(dis(p[0],b) > dis(p[0],a)) return true;
else return false;
}
else {
if(m>0) return true;
else return false;
}
}
int main(){
// freopen("1.in","r",stdin);
double l;
while(scanf("%d%lf",&n,&l)!=EOF){
for(int i=0;i<n;i++) {
scanf("%lf%lf",&p[i].x,&p[i].y);
}
sort(p,p+n,cmp);
sort(p+1,p+n,cmp1);
s[0].x = p[0].x; s[0].y = p[0].y;
s[1].x = p[1].x; s[1].y = p[1].y;
int top=1;
for(int i=2;i<n;i++) {
while(top>=1 && cross(s[top-1],s[top],p[i]) < 0) top--;
s[++top] = p[i];
}
double num = 0;
for(int i=0;i<top;i++) {
num += dis(s[i],s[i+1]);
}
num += dis(s[0],s[top]);
num += (2*PI*l);
printf("%.f\n",num);
}
return 0;
}
poj 2007 Scrambled Polygon
题意:按照一第一个输入的点排序。(读错题)
思路:极角排序下。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
const int mod = 1e9+7;
#define ll long long
#define llu unsigned long long
using namespace std;
map<string,int>mp;
const int maxn = 100550+10;
const double eps = 0.0000001;
const double PI = 3.1415926;
int v[maxn],a[maxn];
struct Point {
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
};
vector<Point>vec;
int n;
Point p[150];
Point p4[150],p3[150],p2[150],p1[150];
double cross(Point a,Point b,Point c) {
return ((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
}
double dis(Point a,Point b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(Point a,Point b) {
if(a.x != b.x) return a.x<b.x;
else return a.y<b.y;
}
bool cmp1(Point a,Point b) {
double m = cross(p[0],a,b);
if(fabs(m-0.0) <= eps) {
if(dis(p[0],b) > dis(p[0],a)) return true;
else return false;
}
else {
if(m>0) return true;
else return false;
}
}
int main(){
// freopen("1.in","r",stdin);
scanf("%lf%lf",&p[0].x,&p[0].y);
double tx = p[0].x,ty = p[0].y;
int d = 0;
int tp = 1;
while(scanf("%lf%lf",&p[tp].x,&p[tp].y)!=EOF){tp++;}
sort(p,p+tp,cmp);
sort(p+1,p+tp,cmp1);
for(int i=0;i<tp;i++) {
if(p[i].x == tx && p[i].y == ty) {
d = i;
vec.push_back(p[i]);
break;
}
}
for(int i=d+1;i<tp;i++) {
vec.push_back(p[i]);
}
for(int i=0;i<d;i++) {
vec.push_back(p[i]);
}
for(int i=0;i<vec.size();i++) {
printf("(%.0f,%.0f)\n",vec[i].x,vec[i].y);
}
return 0;
}
poj 1228 Grandpa’s Estate
题意: 给n个点,问是不是一个稳定的凸包。
思路:第一次见这样的题,上网搜了一下,是让求稳定凸包。
AC代码:
//代码虽然ac了,但是有讨论区的数据过不去,还要更正。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
const int mod = 1e9+7;
#define ll long long
#define llu unsigned long long
using namespace std;
map<string,int>mp;
const int maxn = 100550+10;
const double eps = 0.0000001;
const double PI = 3.1415926;
struct Point {
double x,y;
Point(double x=0,double y=0): x(x),y(y){}
};
Point p[1100],s[1100];
bool cmp(Point a,Point b){
if(a.x!=b.x) return a.x < b.x;
else return a.y < b.y;
}
double dis(Point a,Point b){
return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cross(Point a,Point b,Point c) {
return ((b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x));
}
bool cmp1(Point a,Point b){
double m = cross(p[0],a,b);
if(fabs(m-0)<=eps) {
if(dis(p[0],b) > dis(p[0],a)) return true;
else return false;
}else {
if(m>0) return true;
else return false;
}
}
int main(){
// freopen("1.in","r",stdin);
int t; scanf("%d",&t);
while(t--) {
int n; scanf("%d",&n);
for(int i=0;i<n;i++) {
scanf("%lf%lf",&p[i].x,&p[i].y);
}
if(n<=5) {
printf("NO\n"); continue;
}
sort(p,p+n,cmp);
sort(p+1,p+n,cmp1);
s[0].x = p[0].x; s[0].y = p[0].y;
s[1].x = p[1].x; s[1].y = p[1].y;
int top=1;
for(int i=2;i<n;i++) {
while(top>=1 && cross(s[top-1],s[top],p[i])<0) top--;
s[++top] = p[i];
}
// for(int i=0;i<=top;i++) {
// printf("%lf %lf\n",p[i].x,p[i].y);
// }cout<<endl;
bool pd = true;
//判断是否是稳定凸包
for(int i=1;i<top;i++) {
// printf("%lf %lf\n",p[i].x,p[i].y);
if(cross(s[i-1],s[i],s[i+1])!=0 && cross(s[i],s[(i+1)>n?(i+1)%n : i+1],s[(i+2)>n?(i+2)%n : i+2])!=0) {
pd = false; break;
}
}
if(pd) printf("YES\n");
else printf("NO\n");
}
return 0;
}
poj 3348 Cows
题意:给n个点,每50平米养一只,能养多少只。
思路:求凸包,在求个面积。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
const int mod = 1e9+7;
#define ll long long
#define llu unsigned long long
using namespace std;
map<string,int>mp;
const int maxn = 100550+10;
const double eps = 0.0000001;
const double PI = 3.1415926;
struct Point {
double x,y;
Point(double x=0,double y=0): x(x),y(y){}
};
Point p[11000],s[11000];
bool cmp(Point a,Point b){
if(a.x!=b.x) return a.x < b.x;
else return a.y < b.y;
}
double dis(Point a,Point b){
return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cross(Point a,Point b,Point c) {
return ((b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x));
}
bool cmp1(Point a,Point b){
double m = cross(p[0],a,b);
if(fabs(m-0)<=eps) {
if(dis(p[0],b) > dis(p[0],a)) return true;
else return false;
}else {
if(m>0) return true;
else return false;
}
}
int main(){
// freopen("1.in","r",stdin);
int n;
while(scanf("%d",&n)!=EOF) {
for(int i=0;i<n;i++) {
scanf("%lf%lf",&p[i].x,&p[i].y);
}
sort(p,p+n,cmp);
sort(p+1,p+n,cmp1);
s[0].x = p[0].x; s[0].y = p[0].y;
s[1].x = p[1].x; s[1].y = p[1].y;
int top = 1;
for(int i=2;i<n;i++) {
while(top>=1 && cross(s[top-1],s[top],p[i])<=0) top--;
s[++top] = p[i];
}
double S = 0;
for(int i=0;i<top;i++) {
S += abs(s[i].x*s[i+1].y-s[i+1].x*s[i].y);
}
S += abs(s[top].x*s[0].y - s[0].x*s[top].y);
S = S/2;
// printf("%lf\n",S);
printf("%d\n",(int)S/50);
}
return 0;
}
推荐一道 poj1987 The Fortified Forest 题意简单,要状态压缩(可惜我太菜,还不会)。