↓ 跳过正文
  1. Posts/

poj 1379 Run Away (模拟退火)

·546 字·2 分钟

poj 1379题目链接

题意:给出一个矩形区域的长宽,给出区域中若干点,问距离所有点的最近距离的最大值是多少。

思路:很容易想到模拟退火。

比赛的时候因为忘记判断矩形边界导致答案错得离谱2333

加上之后1A

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年08月28日 星期一 19时10分47秒
  4File Name :code/poj/1379.cpp
  5 ************************************************ */
  6#include <cstdio>
  7#include <cstring>
  8#include <iostream>
  9#include <algorithm>
 10#include <vector>
 11#include <queue>
 12#include <set>
 13#include <map>
 14#include <string>
 15#include <cmath>
 16#include <cstdlib>
 17#include <ctime>
 18#define fst first
 19#define sec second
 20#define lson l,m,rt<<1
 21#define rson m+1,r,rt<<1|1
 22#define ms(a,x) memset(a,x,sizeof(a))
 23typedef long long LL;
 24#define pi pair < int ,int >
 25#define MP make_pair
 26using namespace std;
 27const double eps = 1E-8;
 28const int dx4[4]={1,0,0,-1};
 29const int dy4[4]={0,-1,1,0};
 30const int inf = 0x3f3f3f3f;
 31#define INF 1e8
 32#define MAX 1e6
 33#define MAXN 1005
 34double X,Y;
 35int n;
 36struct Point {
 37    double x, y;
 38    double d;
 39    Point() {}
 40    Point(double _x, double _y) : x(_x), y(_y) {}
 41    Point operator +(const Point &p) const {
 42	return Point(x + p.x, y + p.y);
 43    }
 44    Point operator -(const Point &p) const {
 45	return Point(x - p.x, y - p.y);
 46    }
 47    Point operator *(double k) const {
 48	return Point(x * k, y * k);
 49    }
 50    bool ok ()
 51    {
 52	if (x<0||y<0||x>X||y>Y) return false;
 53	return true;
 54    }
 55} p[MAXN];
 56const Point d[4] = {Point(-1, 0), Point(0, -1), Point(1, 0), Point(0, 1)};
 57double dis(const Point &a, const Point &b) {
 58    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
 59}
 60void solve(const Point *p, int n, Point &ret) {
 61    int i, j;
 62    double x, cur, ans = 0;
 63    const double delta = 0.95;
 64    bool tag;
 65    Point nxt;
 66    for (ret = p[0], x = (X+Y)/10; x > eps; x *= delta) {
 67	for (tag = true; tag;) {
 68	    for (tag = (i = 0); i < 4; ++i) {
 69		nxt.x = ret.x + dx4[i] * x * X;
 70		nxt.y = ret.y + dy4[i] * x * Y;
 71		if (!nxt.ok()) continue;
 72		for (cur=inf, j = 0; j < n; ++j) cur = min(cur,dis(nxt,p[j]));
 73		if (cur > ans) {
 74		    ans = cur; ret = nxt; tag = true;
 75		    break;
 76		}
 77	    }
 78	}
 79    }
 80
 81}
 82int main()
 83{
 84#ifndef  ONLINE_JUDGE
 85    freopen("code/in.txt","r",stdin);
 86#endif
 87    int T;
 88    cin>>T;
 89    while (T--)
 90    {
 91	scanf("%lf%lf%d",&X,&Y,&n);
 92	for ( int i = 0 ;  i < n ; i++)
 93	    scanf("%lf %lf",&p[i].x,&p[i].y);
 94	Point ans;
 95	solve(p,n,ans);
 96
 97	printf("The safest point is (%.1f, %.1f).\n",ans.x,ans.y);
 98
 99    }
100#ifndef ONLINE_JUDGE
101    fclose(stdin);
102#endif
103    return 0;
104}

相关文章

seerc 2014 Circle of digits (二分+后缀数组)

·979 字·2 分钟
题目链接 题意:把一个长度为 n 的只由数字构成的串分成 k 个不为空的子串,使得最大的串最小(大小是指串所对应的十进制数的大小)。 思路:由于长度为 x 的串肯定大于长度为 x-1 的串,因此很容易想到,我们要尽可能使得 k 组串的长度平均(避免出现某一个串的长度非常大的情况)。

seerc 2014 D - Frame (傻逼题)

·232 字·1 分钟
题目链接 思路:注意xy-(x-2)*(y-2)=2x+2y-4,一定被2整除。因此siz为2的也是合法的。这个比较容易忘掉。 其他的判定条件都很好想。具体见代码; 代码实现 1#include <cstdio> 2#include <cstring> 3#include <iostream> 4#include <algorithm> 5#include <vector> 6#include <queue> 7#include <set> 8#include <map> 9#include <string> 10#include <cmath> 11#include <cstdlib> 12#include <ctime> 13#define fst first 14#define sec second 15#define lson l,m,rt<<1 16#define rson m+1,r,rt<<1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair < int ,int > 20#define MP make_pair 21using namespace std; 22const double eps = 1E-8; 23const int dx4[4]={1,0,0,-1}; 24const int dy4[4]={0,-1,1,0}; 25const int inf = 0x3f3f3f3f; 26int X,Y; 27bool ok( int a) 28{ 29 if (a==2) return true; 30 if (X%a==0&&(Y-2)%a==0) return true; 31 if (Y%a==0&&(X-2)%a==0) return true; 32 if (X%a==1&&Y%a==1) return true; 33 34 return false; 35} 36int main() 37{ 38 // freopen("in.txt","r",stdin); 39 40 while (~scanf("%d%d",&X,&Y)) 41 { 42 int n; 43 scanf("%d",&n); 44 while (n--) 45 { 46 int x; 47 scanf("%d",&x); 48 // cout<<"x:"<<x<<endl; 49 if (ok(x)) puts("YES"); 50 else puts("NO"); 51 } 52 } 53return 0; 54}

seerc 2014 A Banks (暴力)

·356 字·1 分钟
题目链接 题意:n个数围成一圈,对于负数可以进行magic操作,也就是取反,但是会影响到左右相邻的,加上这个负数。问最少进行多少次magic操作,使得所有数都是非负。 思路:我们知道,如果一个负数想变成整数的话,只能通过magic 操作。唯一可能影响次数的就是顺序。

hdu 5036 Explosion||2014 北京区域赛网络赛 (概率+bitset优化的状态压缩+floyd传递闭包)

题目链接 题意:有n扇门,n种钥匙,一一对应。每扇门打开后可能得到k把钥匙(k可能为0)。一扇门还可以用一颗炸弹炸开。现在问要开所有门,使用炸弹的期望个数。 思路:状态压缩。用一个二进制串表示每扇门能打开的门的信息,对应的位上为1表示能打开,为0表示不能打开。

codeforces #368 div 2 C. Pythagorean Triples (构造,数学)

·953 字·2 分钟
题目链接 题意:给出一个数,问包含这个数三个数组成的勾股数,输出另外两个数。 思路: 所谓勾股数,就是当组成一个直角三角形的三边长都为正整数时,我们就称这一组数为勾股数. 那么,组成一组勾股数的三个正整数之间,是否具有一定的规律可寻呢?下面我们一起来观察几组勾股数: 规律一:在勾股数(3,4,5)、(5,12,13)、(7,24,25)(9,40,41)中,我们发现 由(3,4,5)有:32=9=4+5 由(5,12,13)有:52=25=12+13 由(7,24,25)有:72=49=24+25 由(9,40,41)有:92=81=40+41. 即在一组勾股数中,当最小边为奇数时,它的平方刚好等于另外两个连续的正整数之和.因此,我们把它推广到一般,从而可得出以下公式: ∵(2n+1)²=4n²+4n+1=(2n²+2n)+(2n²+2n+1) ∴(2n+1)²+(2n²+2n)²=(2n²+2n+1)²(n为正整数) 证明(略) 勾股数公式一:(2n+1,2n²+2n,2n²+2n+1)(n为正整数) 规律二:在勾股数(6,8,10)、(8,15,17)、(10,24,26)中,我们发现 由(6,8,10)有:62=36+2×(8+10) 由(8,15,17)有:82=64=2×(15+17) 由(10,24,26)有:102=100=2×(24+26) 即在一组勾股数中,当最小边为偶数时,它的平方刚好等于两个连续整数之和的二倍,推广到一般,从而可得出另一公式: ∵(2n)2=4n2=2[(n2-1)+(n2+1)] ∴(2n)2+(n2-1)2=(n2+1)2(n≥2且n为正整数) 证明(略) 勾股数公式二:(2n,n²-1,n²+1)(n≥2且n为正整数) 利用以上两个公式,我们可以快速写出各组勾股数.